//alert
var commonMessageFn = null;
(function($) {
	commonMessageFn = function () {
		$.fn.extend( {
			'message' : function(options) {
				//className 可以有alert,alert-success,alert-info, alert-error 等选项，对应不同的样式
				if(!options.msg){
					options.msg = ''; //如果小黄条报错信息为undefined或者null，则默认为空
				} else {
					options.msg = String(options.msg);
				}
				switch (options.type){
					/*2017.2.8 byzym 修改系统提示信息*/
					case 'warning' :
						options.className = 'alert-warningYellow';
						options.title = '提示：';
						options.class = 'font-size: 26px;position: absolute;right: 20px;color:#434649;';
						break;
					case 'success' :
						options.className = 'alert-successGreen';
						options.title = '';
						options.class = 'font-size: 26px;position: absolute;right: 10px;';
						break;
					case 'error':
						options.className = 'alert-dangerRed';
						options.title = '错误：';
						options.class = 'font-size: 40px;position: absolute;right: 20px;';
						break;

				}
				options = $.extend( {
					type : options.type,
					msg : options.msg,
					existTime: options.existTime || 5000
				}, options);
				/*2017.1.14 byzym 修改alert*/
				var div = $('<div data-name="warMing" class="' +options.className+ '" ' +
					'style="min-width: 350px;text-align: center;z-index:9999999;display:none;min-height:25px;line-height:25px;position:fixed;box-shadow: 1px 2px 3px #AAAAAA;">'
					+'<div style="display:inline-block;"><div class="pull-left mLeft10">' +
					'<strong>'+ options.title+'</strong></div>'
					+'<div data-name="optionMsg" style="text-align: left;max-width: 1200px"' +
					' class="pull-left mLeft10"><span></span></div></div>' +
					'<a href="javascript:" class="closeAlert" style="line-height: 25px;color: #FFF;'+options.class+'">×</a></div>');

				var divObj = $(div),
					types = options.type,
					intval = 0,
					marginLeft, left, height, borderRai;
				divObj.find('.closeAlert').click(function(){
					clearTimeout(intval);
					$(this).closest("div[data-name='warMing']").remove();
				});
				divObj.find('[data-name="optionMsg"] span')[!options.isText ? 'html' : 'text'](options.msg.replace(/%#W7Ox0Ze%#/g,'<a href=\"').replace(/%#uIGOykJW%#/g,'" target="_blank" >').replace(/%#ulvupSta%#/g,'</a>')
					.replace('This product price increase is unacceptable. The price of products cannot be greatly increased.', '修改价格与现有价格差异过大，请修改价格信息重新提交')
					.replace('The status of order(ordersn: 200704GRU1JN3Y) is wrong.', '包裹不在待揽收状态，请移除。')
					.replace('Order (ordersn: 20071023Y16W3C, forderid: 2390845657436160613) has been bind to first mile code.', '包裹重复组包，请移除')
					.replace('system error.system error.', '系统错误，请稍后重试')
					.replace('the FM status is not supported', 'shopee大包运单号揽收时间已超期，无法继续组包。请将上传失败的小包移除后重新上传。')
					.replace('the SLS TN is bind by other FM code.', '包裹重复组包，请移除')
					.replace('existed sls_tracking_number pickup by SUR400027113965.', '包裹已组包SUR400027113965，请移除')
					.replace('Invalid Params: the whs_id cannot be changed', '多店铺揽收仓库不一致，请联系shopee经理修改')
					.replace('The status of order(ordersn: 200704GRU1JN3Y) is wrong.', '该店铺不支持上门揽收')
					.replace('The shop has no permission for the first mile shipment method: dropoff.', '该店铺不支持卖家自送')
					.replace('the SLS TN is bind by other FM code.', '包裹重复组包，请移除'));
				$('body').append(divObj);
				var width=divObj.width();
				if(types === 'success'){
					marginLeft = '-' + width / 2 + 'px';
					left = '50%';
					borderRai = '3px';
				}else{
					marginLeft = '0';
					left = '0';
					borderRai = '0';
				}
				divObj.css({'margin-left':marginLeft,'left':left,'border-bottom-left-radius':borderRai,'border-bottom-right-radius':borderRai});
				//divObj.css({"top":0,"left":0});
				height = divObj.height();
				//divObj.css({"position":"fixed"});
				height = 100;
				divObj.css('top', '-' + height + 'px');
				divObj.show();
				if(divObj.show()){
					divObj.animate({'top': '0'}, 800);
				}

				if(options.type !== 'error'){
					intval = setTimeout(
						function(){
							divObj.animate({'top': -height}, 400, function(){
								divObj.remove();
							});
						},
						options.existTime

					);
					/* //隐藏对象
                    setTimeout(function(){divObj.toggle(options.speed);},options.existTime);*/

					/*!//移除对象
                    setTimeout(function(){divObj.remove();},options.existTime+5000);*/
				}else{
					intval = setTimeout(
						function(){
							divObj.animate({'top': -height}, 400, function(){
								divObj.remove();
							});
						},
						options.existTime
					);

					/*!//隐藏对象
                   setTimeout(function(){divObj.toggle(options.speed);},options.existTime);*/

					/*!//移除对象
                    setTimeout(function(){divObj.remove();},options.existTime+8000);*/
				}
				return {
					close: function () {
						clearTimeout(intval);
						divObj.animate({'top': -height}, 400, function(){
							divObj.remove();
						});
					}
				}
			}
		});
	};
	commonMessageFn();
    return this;
})(jQuery);

function pover(selector,options){
	var node = document.createElement("span");
		options = $.extend({
			bgColor: "#ff0000",
			type : "错误信息",
	    	content : "网络链接超时"
		},options);
	$(node).css("padding","3px 4px")
		   .css("cursor","pointer")
		   .css("line-height","18px")
		   .css("height","18px")
		   .css("color","#fff")
		   //.css("display","block")
		   .css("background-color",options.bgColor)
		   .css("font-weight","600");
	$(node).attr("data-html","true")
		   .attr("data-toggle","popover")
		   .attr("data-trigger","hover")
		   .attr("data-placement","right")
		   .attr("data-content",options.content);
	$(node).html(options.type);
	$(selector).append(node);
	$('[data-toggle=popover]').popover();
}

// 关闭当前窗口
function closeWin(){
	window.opener=null;window.open('','_self');window.close();
}


//倒计时  （使用方法：addTimer("timer1", 604800); ）
var addTimer = function () {
	var list = [],
		interval,
		obj, d, h, m, s, i;

	//计算倒计时时间
	var computerTimeFn = function (time, dFlag, hFlag, mFlag, sFlag) {
		dFlag && (d = Math.floor(time / 86400));
		hFlag && (h = Math.floor((time % 86400) / 3600));
		mFlag && (m = Math.floor(((time % 86400) % 3600) / 60));
		sFlag && (s = Math.floor(((time % 86400) % 3600) % 60));
	};

	var go = function () {
		if (!list.length) {
			clearTimeout(interval);
			interval = null;
            // list = null;
            obj = null;
            d = null;
            h = null;
            m = null;
            s = null;
            i = null;
            return;
		}

		for (i = 0; i < list.length; i++) {
			if (!list[i].dom) {
				obj = document.getElementById(list[i].id);
				list[i].dom = obj;
			} else {
				obj = list[i].dom;
			}
			if (!obj) {
				list.splice(i--, 1);
				continue;
			}

			obj.innerHTML = getTimerString(list[i].time ? list[i].time -= 1 : 0, list[i].type);

			if (list[i].time <= 0) {
				list.splice(i--, 1);
				continue;
			}
		}
	};

	var getTimerString = function (time, type) {
		if (time > 0 && type === 'shipping') {
			computerTimeFn(time, 1, 1, 1);
			return '剩余发货：<span class="f-red">' + d + '</span>天<span class="f-red">' + h + '</span>小时<span class="f-red">' + m + '</span>分';
		} else if (time > 0 && type === 'tracking') {
			computerTimeFn(time, 1, 1, 1);
			if (d >= 3) {
				return '<span class="gray-c">单号有效：' + d + '天' + h + '小时' + m + '分</span>';
			} else {
				return '<span class="f-red">单号有效：' + d + '天' + h + '小时' + m + '分</span>';
			}
		} else if (time <= 0 && type === 'shipping') {
			return '<span class="f-red">剩余发货：已到期</span>';
		} else if (time <= 0 && type === 'tracking') {
			return '<span class="f-red">单号有效：已到期</span>';
		} else if (time > 0 && type === 'issue') {
			computerTimeFn(time, 1, 1, 1, 1);
			return '<span class="f-red">' + d + '</span>天<span class="f-red">' + h + '</span>小时<span class="f-red">' + m + '</span>分<span class="f-red">' + s + '</span>秒';
		} else if (type === 'shippingNew') {//虚拟组包 ---未发货包裹剩余发货时间
			if (time > 0) {
				computerTimeFn(time, 1, 1, 1);
				return '<span class="f-red">' + d + '</span>天<span class="f-red">' + h + '</span>小时<span class="f-red">' + m + '</span>分';
			} else {
				return '<span class="f-red">已到期</span>';
			}
		}
	};

	return function (id, time, type) {
		if (!interval) interval = setInterval(go, 1000);
		list.push({
			id: id,
			time: time,
			type: type
		});
	};
}();


//倒计时  （使用方法：addTimer("timer1", 604800); ）
var addProductTimer = function () {
	var list = [],
		interval,
		obj, d, h, m, i;

	//计算倒计时时间
	var computerTimeFn = function (time, dFlag, hFlag, mFlag) {
		dFlag && (d = Math.floor(time / 86400));
		hFlag && (h = Math.floor((time % 86400) / 3600));
		mFlag && (m = Math.floor(((time % 86400) % 3600) / 60));
	};

	var go = function () {
		if (!list.length) {
			clearTimeout(interval);
			interval = null;
            // list = null;
            obj = null;
            d = null;
            h = null;
            m = null;
            i = null;
            return;
		}

		for (i = 0; i < list.length; i++) {
			if (!list[i].dom) {
				obj = document.getElementById(list[i].id);
				list[i].dom = obj;
			} else {
				obj = list[i].dom;
			}
			if (!obj) {
				list.splice(i--, 1);
				continue;
			}

			obj.innerHTML = getTimerString(list[i].time ? list[i].time -= 1 : 0);

			if (list[i].time <= 0) {
				list.splice(i--, 1);
				continue;
			}
		}
	};

	var getTimerString = function (time) {
		if (time > 0) {
			computerTimeFn(time, 1, 1, 1);
			return '<p class="m0">剩余：</p><p class="m0"><span class="f-red">' + d + '</span>天<span class="f-red">' + h + '</span>小时<span class="f-red">' + m + '</span>分</p>';
		} else {
			return '<p class="m0 f-red">已到期</p>';
		}
	};

	return function (id, date, now) {
		if (!interval) interval = setInterval(go, 1000);

		list.push({
			id: id,
			time: (new Date(date) - new Date(now)) / 1000
		});
	};
}();
//方法可能重复
//倒计时  （使用方法：addTimer("timer1", 604800); ）
//采购单
var addProductTimerS = function () {
	var list = [],
		optionObj,
		interval,
		obj, d, h, m, i;

	//计算倒计时时间
	var computerTimeFn = function (time, dFlag, hFlag, mFlag) {
		dFlag && (d = Math.floor(time / 86400));
		hFlag && (h = Math.floor((time % 86400) / 3600));
		mFlag && (m = Math.floor(((time % 86400) % 3600) / 60));
	};

	var go = function () {
		if (!list.length) {
			clearTimeout(interval);
			interval = null;
            // list = null;
            obj = null;
            d = null;
            h = null;
            m = null;
            i = null;
            return;
		}

		for (i = 0; i < list.length; i++) {
			if (!list[i].dom) {
				obj = document.getElementById(list[i].id);
				list[i].dom = obj;
			} else {
				obj = list[i].dom;
			}
			if (!obj) {
				list.splice(i--, 1);
				continue;
			}

			obj.innerHTML = getTimerString(list[i].time ? list[i].time -= 1 : 0, list[i]);

			if (list[i].time <= 0) {
				list.splice(i--, 1);
				continue;
			}
		}
	};

	var getTimerString = function (time, items) {
		if (time > 0 && optionObj && optionObj.showTimeDivision) {
			computerTimeFn(time, 1, 1, 1);
			// 倒计时未结束 显示 剩余：XX天XX小时XX分
			return '<p class="m0 fRed">剩余：' + d + '天' + h + '小时' + m + '分</p>';
		} else if (time > 0) {
			computerTimeFn(time, 1, 1);
			// 倒计时未结束 显示 剩余：XX天XX小时（默认）
			return '<p class="m0">剩余：<span class="fRed">' + d + '</span>天<span class="fRed">' + h + '</span>小时';
		} else if (optionObj && optionObj.isSheinRequestDeliveryTime) {
			// shenin 备货管理 最晚发货时间 超过后 显示最晚发货时间， ps: 默认显示已到期
			return '<p class="m0">最晚发货:</p><p class="m0">' + items.date + '</p>';
		} else {
			return '<p class="m0 fRed">已到期</p>';
		}
	};

	return function (id, date, now, option) {
		if (!interval) interval = setInterval(go, 1000);
		if (option) optionObj = option;

		list.push({
			id: id,
			time: (new Date(date) - new Date(now)) / 1000,
			date: date
		});
	};
}();

//时间递增轮询
var addIncreaseTimer = function () {
	var list = [],
		currentDataType,
		interval,
		obj, d, h, m, i;

	//计算倒计时时间
	var computerTimeFn = function (time, dFlag, hFlag, mFlag) {
		dFlag && (d = Math.floor(time / 86400));
		hFlag && (h = Math.floor((time % 86400) / 3600));
		mFlag && (m = Math.floor(((time % 86400) % 3600) / 60));
	};

	var go = function () {
		if (!list.length) {
			clearTimeout(interval);
			interval = null;
			// list = null;
			obj = null;
			d = null;
			h = null;
			m = null;
			i = null;
			return;
		}
		for (i = 0; i < list.length; i++) {
			if (!list[i].dom) {
				obj = document.getElementById(list[i].id);
				list[i].dom = obj;
			} else {
				obj = list[i].dom;
			}
			if (!obj) {
				list.splice(i--, 1);
				continue;
			}
			obj.innerHTML = getTimerString(list[i].time ? list[i].time += 1 : 0, currentDataType);
		}
	};

	var getTimerString = function (time, currentDataType) {
		if (time > 0) {
			computerTimeFn(time, 1, 1, 1);
			if (currentDataType === 1) {
				if ((d * 24 + h) > 36) {
					return '超时：<p class="m0"><span class="f-orange">' + Number(d * 24 + h - 36) + '</span>小时<span class="f-orange">' + m + '</span>分</p>';
				} else {
					return '';
				}
			} else {
				return '<p class="m0"><span class="f-orange">' + d + '</span>天<span class="f-orange">' + h + '</span>小时<span class="f-orange">' + m + '</span>分</p>';
			}
		}
	};

	return function (id, date, now, dataType) {
		if (!interval) interval = setInterval(go, 1000);
		currentDataType = dataType;
		list.push({
			id: id,
			time: time = (new Date(now) - new Date(date)) / 1000
		});
	};
}();

//两时间相减
//styleColor为更改字体颜色
var diffTimeMethod = function () {
	var list = [],
		currentDataType,
		d, h, m;

	//计算倒计时时间
	var computerTimeFn = function (time, dFlag, hFlag, mFlag) {
		dFlag && (d = Math.floor(time / 86400));
		hFlag && (h = Math.floor((time % 86400) / 3600));
		mFlag && (m = Math.floor(((time % 86400) % 3600) / 60));
	};
	var getTimerString = function (time, styleColor) {
		if (time > 0) {
			if (currentDataType === 1) {
				computerTimeFn(time, 1, 1);
				if ((d * 24 + h) > 36) {
					return '<p class="m0"><span class="' + (styleColor ? styleColor : 'f-orange') + '">耗时：'
						+ Number(d * 24 + h - 36) + '</span>小时</p>';
				} else {
					return '';
				}

			} else {
				computerTimeFn(time, 1, 1, 1);
				return '<p class="m0"><span class="' + (styleColor ? styleColor : 'f-orange') + '">'
					+ d + '</span>天<span class="' + (styleColor ? styleColor : 'f-orange') + '">'
					+ h + '</span>小时<span class="' + (styleColor ? styleColor : 'f-orange') + '">'
					+ m + '</span>分</p>';
			}
		} else {
			return '';
		}
	};

	return function (id, date, now, dataType, styleColor) {
		var time = (new Date(date) - new Date(now)) / 1000,
		    obj = document.getElementById(id);
		currentDataType = dataType;

		obj.innerHTML = getTimerString(time, styleColor);
	};
}();


// 检查后台处理状态(场景：后台处理时间较长，前台定时请求后台的执行状态)
var intervalProcessStatus = null; //定时请求后台状态的定时器，在不需要继续请求的时候清除定时器
var checkProcessStatus = (function (){
	var uuId, callBack, pm;
    var go = function () {
        $.ajax({
            type: 'POST',
            url: gitWinLocHref() + 'checkProcess.json',
            data: {uuid: uuId},
            dataType: 'json',
            success: function(data){
                pm = data.processMsg;
                if(pm === undefined || +pm.code){
                    clearInterval(intervalProcessStatus);
                    intervalProcessStatus = null;
                }
                callBack(pm);
            }
        });
    };
	return function (uuid, callback) {
        if (!intervalProcessStatus) intervalProcessStatus = setInterval(go, 3000);
		callBack = callback;
		uuId = uuid;
	};
})();

/**
 * 提供两个检测状态的方法，依赖checkProcessStatus 方法
 * 样例
 * myjSyncProgressBar({
		uuid: res.uuid,
		messageTip: '同步数据',
		backdrop: true, // 控制点击背景是否可以关闭，true 可关闭| false 不可关闭，默认true 可关闭
		close: function(r){
			// 入参r为，进度状态，true为已完成，false为进行中
			if (r) $("#3 div").trigger("click");
			// 返回 true 阻止关闭，返回 false 或者不返回 默认关闭
			return !r;
		},
		success: function (res, r) {
			// 入参res为轮训进度接口的最后一次结果, 入参r为进度框是否关闭状态，true为已关闭，false为未关闭
			obj.disabled = false;
			if (r) $("#3 div").trigger("click");
		}
	});
 * @param o 配置参数 {uuid: '', messageTip: '提示头', backdrop: true|false 控制点击背景, success: function(接口数据, 进度框关闭状态true|false), close: function(进度完成状态true|false):true|false 可阻止关闭进度框}
 * return {checkStatus:func, checkClose:func}
 */
var myjSyncProgressBar = (function($){
	/**
	 * 同步进度条封装
	 * @param o 配置参数 {uuid: '', messageTip: '提示头', success: function(接口数据, 进度框关闭状态true|false), close: function(进度完成状态true|false)}
	 * @constructor
	 */
	function SyncProgressBar(o) {
		this.config = {
			uuid: '',
			messageTip: '同步数据',
			backdrop: true,
			className: 'in-modal',
			success: function(result, closeStatus) {},
			response: function(result, closeStatus){},
			close: function(status) {
			// 返回 true 阻止关闭，返回 false 不返回 默认关闭
			}
		};
		for (var k in o) {
			if (this.config.hasOwnProperty(k)) {
				this.config[k] = o[k];
			}
		}
		this.closeStatus = false;
		this.status = false;
		// jquery 元素对象
		this.elems = {
			modal: null,
			title: null,
			close: null,
			iconClose: null,
            backdrop: null,
			progress: null,
			progress_stat: null,
			progress_detail: null
		};

		this.init = function() {
			var that = this,
				elem = document.createElement('div'),
				elemHtml = '';

            elem.setAttribute('data-backdrop', 'static');
			elem.className = 'modal ' + this.config.className;
			elemHtml += '<div class="modal-dialog">' +
				'			<div class="modal-content bs-example bs-example-tabs"><div class="modal-header">' +
				'                <button type="button" class="close iconCloseSpb"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>' +
				'                <h4 class="modal-title modalTitleSpb"></h4>' +
				'            </div>' +
				'			 <div class="modal-body tab-content">' +
				'                <div class="progress">' +
				'                    <div class="progress-bar progress-bar-info progress-bar-striped progressSpb" role="progressbar" aria-valuenow=10" aria-valuemin="0" aria-valuemax="100" style="width:0%">' +
				'                    </div>' +
				'                </div><div class="mTop10">' +
				'                    状态：<span class="fRed progresStatSpb">进行中...</span><br/>' +
				'                    详情：<div class="progressDetailSpb" style="margin-left:30px; max-height: 400px; overflow-x: auto;"></div>' +
				'                </div>' +
				'            </div>' +
				'			<div class="modal-footer">' +
				'                <button type="button" class="button btn-gray btnCloseSpb">关闭</button>' +
				'            </div></div></div>';

			elem.innerHTML = elemHtml;
			$('body').append(elem);
			this.elems.modal = $(elem);
			this.elems.title = this.elems.modal.find('.modalTitleSpb');
			this.elems.close = this.elems.modal.find('.btnCloseSpb');
			this.elems.iconClose = this.elems.modal.find('.iconCloseSpb');
			this.elems.progress = this.elems.modal.find('.progressSpb');
			this.elems.progress_stat = this.elems.modal.find('.progresStatSpb');
			this.elems.progress_detail = this.elems.modal.find('.progressDetailSpb');
			this.elems.modal.modal('show');
			this.elems.title.text(this.config.messageTip);
			this.elems.close.on('click', function(ev){
				that.onClose();
			});
			this.elems.iconClose.on('click', function(ev){
				that.onClose();
			});

            if (this.config.backdrop) {
                this.elems.backdrop = this.elems.modal.find('.modal-backdrop');
                this.elems.backdrop.off('click').on('click', function(ev){
                    that.onClose();
                });
            }
			this.checkProcessStatus();
		};
		this.checkStatus = function() {
			return this.status;
		};
		this.checkClose = function() {
			return this.closeStatus;
		};
		this.closeModal = function() {
			this.elems.modal.modal('hide');
		};
		this.checkProcessStatus = function() {
			var p = 0, that = this;		// 记录进度条的值
			var $progressBar = this.elems.progress;
			// 先隐藏起来(防止出现进度条后退的效果)
			$progressBar.css({width: '0%', display: ''});
			checkProcessStatus(this.config.uuid, function (data) {
				var num = data.num % 100;
				var status = "进行中...";

				if (num < p && data.code != 1) {
					// 为了去掉变为n->0时的动画效果，在此先隐藏，然后再置0，最后再定时显示出来
					$progressBar.css('display', 'none');
					setTimeout(function () {
						$progressBar.css("display", "");
					}, 1000);
				}

				p = num;

				if (data.code == 0) {
					$progressBar.css('width', num + '%');
				} else {
					status = '已完成!';
					$progressBar.removeClass('progress-bar-info').addClass('progress-bar-success');
					if (data.code === -1) {
						$progressBar.removeClass('progress-bar-info').addClass('progress-bar-warning');
						status = '失败！';
					}
					$progressBar.css('width', '100%');
					$progressBar.removeClass('active');
					that.status = true;
					data = that.config.success(data, that.closeStatus) || data;
					if (that.closeStatus) {
						that.elems.modal.remove();
					}
				}
				that.elems.progress_stat.html(status);
				that.elems.progress_detail.html(data.msg);
			});
			$progressBar.css('display', 'none');
			setTimeout(function () {
				$progressBar.css({width: '0%', display: ''});
			}, 10);
			that.elems.progress_stat.html('进行中...');
			that.elems.progress_detail.empty();
		};
		this.setProgress = function() {};
		this.setProgressStat = function() {};
		this.setProgressDetail = function() {};
		this.onClose = function() {
			var r = this.config.close(this.status);
			//如果返回true 阻止关闭
			if (!r) {
				this.closeStatus = true;
				this.elems.modal.modal('hide');
				if (this.status) {
					// 删除modal框
					this.elems.modal.remove();
				}
			}
		};
		this.init();
	}

	return function(o){
		var instance = new SyncProgressBar(o);
		return {
			checkStatus: function(){
				return instance.checkStatus();
			},
			checkClose: function(){
				return instance.checkClose();
			},
			closeModal: function () {
				return instance.closeModal();
			}
		}
	}
})(jQuery);

/**
 * 根据name，得到某组checkbox选中的值(多个用逗号分隔)
 */
function getCheckBoxValByName(name){
	var s = '';
	$('input[name="' + name + '"]:checked').each(function(){
		var v = $(this).val();
		if (v.indexOf(',') > - 1){
			v = v.replace(/,/g , '');
		}
		if(s !== ''){
			s = s + ',';
		}
		s = s + v;
	});
	return s;
}

/**
 * 根据name，得到所有checkbox的值（多个用逗号分隔）
 */
var getAllCheckBoxValByName = function(name){
	var s = "";
	$("input[name='"+name+"']").each(function(){
		var v = $(this).val();
		if(s!=""){
			s = s + ",";
		}
		s = s + v;
	});
	return s;
};

/**
 * 选中当前页复选框
 * @param obj
 * @param name
 * @param isVisible 是否只选中非隐藏的复选框，true=是，false=否，有些搜索的地方选中需要用到，只选中显示的，隐藏的不选择
 */
function selAllCurrPage(obj, name, isVisible){
	$('input[name="' + name + '"]' + (isVisible ? ':visible' : '')).prop('checked', $(obj).is(':checked'));
}
/**
 * 字符串格式化
 * 用法1：
 * 	var s = "成功删除&{successNum}个";
 * 	s.format({successNum:20});
 * 用法2：
 * 	var s = "成功删除&{0}个,错误&{1}个";
 * 	s.format(20, "abc");
 *
 */
var formatStrReplace = function(data, result){
    for(var key in data){
		result = returnStringReplaceResult(result, '&{' + key + '}', data[key], false);
    }
    return result;
};
String.prototype.format = function(args) {
    if (arguments.length) {
        var result = this,
            html = result,
            htmlList = '',
            i,ind,len;
        if (arguments.length === 1 && typeof (args) === 'object') {
            if(Array.isArray(args)){
                for(ind = 0, len = args.length; ind < len; ind++){
                    result = html;
                    htmlList += formatStrReplace(args[ind], result);
                }
            }else{
                htmlList = formatStrReplace(args, result);
            }
        }else{
            for(i = 0; i < arguments.length; i++){
                if(Array.isArray(arguments[i])){
                    for(ind = 0, len = arguments[i].length; ind < len; ind++){
                        result = html;
                        htmlList += formatStrReplace(arguments[i][ind], result);
                    }
                }else{
                    result = html;
                    htmlList += formatStrReplace(arguments[i], result);
                }
            }
        }
        return htmlList;
    }else{
        return this;
    }
};

//模板替换
var htmlTemplateChange = function(id,data){
	var str = $('#' + id).html();
	str = str ? str : '';
	str = str.replace(/[\r\n]/g, '').replace(/(^\s{2,})|(\s{2,}$)|(\s{2,})/g, '');
	return str.format(data);
};

/**
 * 日期格式化
 * 用法：
 * new Date(毫秒数).format("yyyy-MM-dd hh:mm:ss");
 */
Date.prototype.format = function(format) {
    /*
     * eg:format="yyyy-MM-dd hh:mm:ss";
     */
    var o = {
        "M+" : this.getMonth() + 1, // month
        "d+" : this.getDate(), // day
        "h+" : this.getHours(), // hour
        "m+" : this.getMinutes(), // minute
        "s+" : this.getSeconds(), // second
        "q+" : Math.floor((this.getMonth() + 3) / 3), // quarter
        "S" : this.getMilliseconds()
        // millisecond
    };

    if (/(y+)/.test(format)) {
        format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4
                        - RegExp.$1.length));
    }

    for (var k in o) {
        if (new RegExp("(" + k + ")").test(format)) {
            format = format.replace(RegExp.$1, RegExp.$1.length == 1
                            ? o[k]
                            : ("00" + o[k]).substr(("" + o[k]).length));
        }
    }
    return format;
};

/**
 * 比较两个字符串日期大小
 * @param startTime 开始日期
 * @param endTime 结束日期
 * @return 如果开始日期等于结束日期，则返回0，
 			如果开始日期大于结束日期，则返回1
 			如果开始日期小于结束日期，则返回-1
 */
function compareDate(startTime, endTime){
	startTime = startTime ? startTime : '';
	endTime = endTime ? endTime : '';
    var start = new Date(startTime.replace('-', '/').replace('-', '/')),
		end = new Date(endTime.replace('-', '/').replace('-', '/'));
    if(start.getTime() === end.getTime()){ //时间戳转换成毫秒数比较 原无法比较 2018.3.21 byzym
        return 0;
    }else if(start > end){
    	return 1;
    }else if(start < end){
    	return -1;
    }
}

// 获取当前时间之前的日期，n代表距今天n+1天之前，如：前60天 getDateStr(59);
var getDateStr = function (n) {
	var myDate = new Date(new Date() - 1000 * 60 * 60 * 24 * n),
		yyyy = myDate.getFullYear(),    //获取完整的年份(4位,1970-????)
		MM = myDate.getMonth() + 1,      //获取当前月份(0-11,0代表1月)
		dd = myDate.getDate();

	if (MM < 10) MM = '0' + MM;
	if (dd < 10) dd = '0' + dd;
	return yyyy + '-' + MM + '-' + dd;
};

/**
 * 判断数组中是否有重复
 * @param arr 传入的数组
 * @returns
 * 如果有重复返回重复的值，如果没有重复返回空串
 *
 */
function isRepeatInArray(arr){
	for(var i = 0; i < arr.length; i++){
		for(var j=i+1; j<arr.length; j++){
			if(arr[i] == arr[j]){
				return arr[i];
			}
		}
	}
	return "";
}

/**
 * 判断数组中是否有重复
 * @param arr 传入的数组
 * @returns 返回去重后的数组
 *
 */
function unique(arr){
	for(var i = 0; i < arr.length; i++){
		for(var j = i + 1; j < arr.length; j++){
			if(arr[i] == arr[j]){         //第一个等同于第二个，splice方法删除第二个
				arr.splice(j, 1);
				j--;
			}
		}
	}
	return arr;
}

/**
 * 判断字符串中是否包含中文
 * @param str
 * @returns {Boolean}
 * 如果包含中文返回true，否则返回false
 */
function isContainChinese(str){
	return /.*[\u4e00-\u9fa5]+.*/.test(str);
}

// 店小秘帮助URL地址
var DXM_HELP_URL = "https://help.dianxiaomi.com";

function baiDuTranslate(str, callback, options,from,to,platform){
	dxmTranslate(str, callback, options,from,to,platform);
}

var DXM_TRANSLATE_URL = "//translate.dianxiaomi.com/translate.json";
function dxmTranslate(str, callback, options,from,to,platform){
	var s = "";
	if(str != undefined && str != ""){
		str = $.trim(str);
		if(str.length > 5000){
			$.fn.message({type:"error",msg:"超过了翻译的最大字数限制"});
			return callback(s, options);
		}
		// 包含中文的时候才进行翻译
		if(!isContainChinese(str)){
			return callback(s, options);
		}
		//str = encodeURIComponent(str);
		var url = DXM_TRANSLATE_URL;

		$.ajax({
	        type : "post",
	        url : url,
	        dataType : "json",
	        data : {q:str,from:from,to:to,platform:platform},
	        success : function(data){
	        	if(data != null){
	        		data = eval(data);
	        		// 如果属性，证明请求失败
	        		if(data.code == 0){
	        			data.data && callback(data.data, options);
	        		}else{
	        			$.fn.message({type:"error",msg:data.msg});
	        		}
	        	}
	        },
	        error:function(err){
	        	$.fn.message({type:"error",msg:"网络连接超时，请稍后再试！"});
	        }
	    });
	}
}

/**fuyi add**/
(function ($, window, location, undefined) {
    var ie = window.xiuxiu;
    if(ie){
		window.imgEdit = function (cosUrl, imageUrl, wcb, selectPhotoFunc) {
			ie.params.allowFullscreen = false;
			ie.params.movie = "";
			ie.params.wmode = "transparent";
			ie.setLaunchVars('file_name', 'filedata');
			ie.setLaunchVars('file_type', 'jpg');
			if (selectPhotoFunc && typeof selectPhotoFunc == 'function'){
				ie.setLaunchVars('preventBrowseDefault', 1);
			}
			ie.setLaunchVars('cropPresets', [{'主图': '800x800'}, {'eBay主图': '1000x1000'}]);
			ie.setLaunchVars('customMenu', [{'decorate': ['basicEdit', 'inpaint', 'trinket', 'text', 'particle', 'effect', 'border', 'magic', 'localFixes']}]);
			ie.setLaunchVars('nav', 'decorate/basicEdit');
			ie.setLaunchVars('customMaterial', location.protocol + '//' + location.host + '/imageditor/custom_material.xml');
			ie.setUploadType(2);
			ie.setUploadURL(location.protocol + '//' + location.host + '/imageditor/file/upload.json');
			ie.onInit = function () {
				imageUrl && ie.loadPhoto(imageUrl);
			};
			ie.onBeforeUpload = function (data, id) {
				ie.setUploadArgs({filetype: data.type, type: 'image', url: imageUrl, filename: data.name});
			};
			ie.onUploadResponse = function (data) {
				var result = eval('(' + data + ')');
				wcb && typeof wcb == 'function' && wcb(result);
			};
			ie.onBrowse = function (channel, multipleSelection, canClose, id) {
				selectPhotoFunc && typeof selectPhotoFunc == 'function' && selectPhotoFunc(multipleSelection, canClose, function (src) {
					ie.loadPhoto(src, false, ie.defaultID, {loadImageChannel: channel});
				});
				return false;
			};
			ie.embedSWF('editor-embeded', 3, '100%', '100%');
			//修正360 flash遮挡
			var o = $('object');
			if(o.params){
				o.params.movie = "";
			}
		};
		window.watermarkEdit = function (watermarkUrl, watermarkId, wcb) {
			ie.params.allowFullscreen = false;
			ie.params.movie = "";
			ie.params.wmode = "transparent";
			ie.setLaunchVars('file_type', 'png');
			ie.setLaunchVars('file_name', 'filedata');
			ie.setLaunchVars('customMenu', [{'decorate': ['basicEdit', 'effect', 'text', 'border', 'magic', 'localFixes', 'particle', 'inpaint']}]);
			ie.setLaunchVars('nav', 'decorate/basicEdit');
			ie.setUploadType(2);
			ie.setUploadURL(location.protocol + '//' + location.host + '/watermark/file/upload.json');
			ie.onInit = function () {
				watermarkUrl && ie.loadPhoto(watermarkUrl);
			};
			ie.onBeforeUpload = function (data, id) {
				ie.setUploadArgs({
					filetype: data.type,
					type: 'image',
					url: watermarkUrl,
					id: watermarkId,
					filename: data.name
				});
			};
			ie.onUploadResponse = function (data) {
				var result = eval('(' + data + ')');
				wcb && typeof wcb == 'function' && wcb(result);
			};
			ie.embedSWF('editor-embeded', 3, '100%', '100%');
			//修正360 flash遮挡
			var o = $('object');
			o.params.movie = "";
		};
	}
})(jQuery, window, window.location);

/**fuyi add end**/
//简单验证
function validateUser(obj){
	var validateStr = $.trim($(obj).val()),
		validateType = $(obj).attr('name'),
		//validateEmail = /^([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+\.(?:com|cn)$/;
		//validateEmail = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9_]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
		// validateEmail = /^([a-zA-Z0-9]+[_|\_|\.|\-]?)*[a-zA-Z0-9_-]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9_-]+\.[a-zA-Z]{2,3}$/;
		// validateEmail = /^([a-zA-Z0-9]|[\_|\.|\-])+@([a-zA-Z0-9]|[\_|\.|\-])*\.[a-zA-Z0-9]+$/,
		validateEmail = /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/,
		validateSingleEmail = /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])$/,
		//validateEmail =  /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/;
		validateName = /^[a-zA-Z0-9][a-zA-Z0-9_-]{3,29}$/,
		validatePassword = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,20}$/,
		validateQQ = /^[1-9][0-9]{4,16}$/,
        $verificode = $('.verificode'),
        msgTitle = '';

	switch (validateType) {
		case 'account':
			msgTitle = '请输入您的用户名！';
			if (validateStr && !validateStr.match(validateName)) {
				$verificode.html('用户名格式不正确！');
				return false;
			}
		break;
		case 'password':
			msgTitle = '密码不能为空！';
			if (validateStr && !validateStr.match(validatePassword)) {
				$verificode.html('密码格式不正确！不能含有空格,必须包含大小写字母、数字,支持特殊字符,长度为8-20个字符！');
				return false;
			}
		break;
		case 'password2':
			msgTitle = '确认密码不能为空！';
			if (validateStr && !validateStr.match(validatePassword)) {
				$verificode.html('确认密码格式不正确！不能含有空格,必须包含大小写字母、数字,支持特殊字符,长度为8-20个字符！');
				return false;
			}
		break;
		case 'shopName':
			msgTitle = '请填写有效的店铺名称';
		break;
		case 'merchantId':
			msgTitle = '请填写有效的商户ID';
		break;
		case 'content':
			msgTitle = '反馈内容不能为空';
		break;
		case 'email':
			msgTitle = '邮箱不能为空';
			if (validateStr && !validateStr.match(validateEmail)) {
				$verificode.html('邮箱格式不正确！');
				return false;
			}
		break;
		case 'singleEmail': //校验防止多个@
			msgTitle = '邮箱不能为空';
			if (validateStr && !validateStr.match(validateSingleEmail)) {
				$verificode.html('邮箱格式不正确！');
				return false;
			}
			break;
		case 'qq':
			msgTitle = 'QQ不能为空';
			if (validateStr) {
				if (!validateStr.match(validateQQ)) {
					$verificode.html('QQ格式不正确！');
					return false;
				}
			}else{
				$verificode.html(msgTitle);
				return false;
			}
		break;
	}

	if (!validateStr){
        $verificode.html(msgTitle);
		return false;
	}
	return true;
}
//字符串内容开头首字母大写
String.prototype.firstUpperCase =  function (){
	var str = this,
		reg = /^[a-z]/i;
	return str.replace(reg,function(str){
		return str.toUpperCase();
	});
};
//单词首字母大写，单词是按空格区分的
String.prototype.wordFirstUpperCase =  function (){
	var str = this,
		strArr = str.split(' '),
		newStrArr = [];

	$.each(strArr, function (index, item) {
		var newItem = item ? $.trim(item).replace(item[0], item[0].toLocaleUpperCase()) : '';
		newStrArr.push(newItem);
	});
	str = newStrArr.join(' ');
	str = str.replace(/\sOr[^a-zA-Z]|\sAnd[^a-zA-Z]|\sOf[^a-zA-Z]|\sAbout[^a-zA-Z]|\sFor[^a-zA-Z]|\sWith[^a-zA-Z]|\sOn[^a-zA-Z]|\sIn[^a-zA-Z]/g, function($1){
		return $1.toLowerCase();
	});
	return str;
};

// 判断是否是图片
function isPic(name){
    var strFilter =".jpeg|.gif|.jpg|.png|.bmp|.pic|";
    if(name.indexOf(".")>-1){
		var p = name.lastIndexOf(".");
		var strPostfix = name.substring(p, name.length) + "|";
		strPostfix = strPostfix.toLowerCase();
		if (strPostfix.indexOf('?') > - 1) strPostfix = strPostfix.split('?')[0];//可能后面还带了一串参数，需要去掉后面的内容
		if(strFilter.indexOf(strPostfix)>-1){
		  return true;
		}
    }
    return false;
}

//将高速下载地址替换为普通下载地址
function getDownloadUrl(url){
	if (url){
		var idx = url.indexOf('.');
        var msgStart = url.substring(idx + 1);
       return 'https://dxmdownload.'+ msgStart;
	}
    return url;
}

// 兼容图片访问地址
function getPicRealUrl(url){
    var realUrl = "";
    if(url){
        if(url.indexOf('http') === -1 && url.indexOf('HTTP') === -1){
            // cos地址
            var cosImgUrl= 'http://cos.myqcloud.com/11000460/';
            // 万象图片地址
            var wxImgUrlPrefix= 'https://XXXXX-10001658.image.myqcloud.com/',
				productImgPrefix= 'https://X-1251220924.picgz.myqcloud.com';
            // 万象图片项目ID(10001658)
            //var wxAppId = "10001658";

            // 判断图片是cos的还是万象的
			var bucket;
            if(url.startWith('wx')){
                bucket = url.split('/')[0];
                realUrl = wxImgUrlPrefix.replace('XXXXX', bucket) + url;
            }else if(url.startWith('/wx')){
                bucket = url.split('/')[1];
                realUrl = wxImgUrlPrefix.replace('XXXXX', bucket) + url;
            }else if (url.startWith('/productimage')) {
				bucket = url.split('/')[1];
				realUrl = productImgPrefix.replace('X', bucket) + url;
			}
			else if (url.startWith('//')) {
				realUrl = 'https:' + url;
			} else {
				if (url === 'static/img/addImg.jpg' || url === 'static/img/kong.png') cosImgUrl = '';//如果是我们默认的图片，不要拼接这个前缀，否则地址是不能访问的
				realUrl = cosImgUrl + url;
			}
        } else{
            realUrl = url;
        }
		//如果有https:http地址的，肯定是有问题的，先优先换成https
		if (realUrl.indexOf('https:http://') !== -1) {
			realUrl = returnStringReplaceResult(realUrl, 'https:http://', 'https://', true);
		}

        //如果是Shopify的图片地址，做下替换
        if (realUrl.indexOf('cdn.shopify.com') !== -1) {
			realUrl = returnStringReplaceResult(realUrl, 'cdn.shopify.com', 'cdn.shopifycdn.net', true);
		}
		//如果是etsy的图片地址，做下替换
        if (realUrl.indexOf('www.etsy.com') !== -1) {
			realUrl = returnStringReplaceResult(realUrl, 'www.etsy.com', 'i.etsystatic.com', true);
		}
        //joom之前做过替换，替换成cdnjoom.dianxiaomi.com的链接需要再还原回去，这里重新替换回去
        if (realUrl.indexOf('cdnjoom.dianxiaomi.com') !== -1) {
			realUrl = returnStringReplaceResult(realUrl, 'cdnjoom.dianxiaomi.com', 'img.joomcdn.net', true);
		}
		//img.joomcdn.net域名又访问不了的，再次替换回去
		// if (realUrl.indexOf('img.joomcdn.net') !== -1) {
		// 		realUrl = returnStringReplaceResult(realUrl, 'img.joomcdn.net', 'cdnjoom.dianxiaomi.com', true);
		// 	}
		if (realUrl.indexOf('my-test-11.slatic.net') !== -1) {
				realUrl = returnStringReplaceResult(realUrl, 'my-test-11.slatic.net', 'my-live.slatic.net', true);
			}
		//亚马逊图片替换
		if (realUrl.indexOf('m.media-amazon.com') !== -1) {
				realUrl = returnStringReplaceResult(realUrl, 'm.media-amazon.com', 'images-na.ssl-images-amazon.com', true);
			}
        //拼多多跨境'https://img.kwcdn.com'替换成'https://kj-img.pddpic.com'
        if (realUrl.indexOf('https://img.kwcdn.com') !== -1) {
			realUrl = returnStringReplaceResult(realUrl, 'https://img.kwcdn.com', 'https://kj-img.pddpic.com', true);
		}
        //速卖通图片带后缀发布会报错，对后缀做下去除处理
        if (realUrl.indexOf('//ae01.alicdn.com/') !== -1 && realUrl.indexOf('?width=') !== -1) {
			realUrl = realUrl.split('?width=')[0];
		}
    }

    return realUrl;
}

//编辑页图片地址替换共用方法
var imgUrlReplace = function (url, type) {
	var newUrl = url;
	//显示的时候替换成cdn-platform.dianxiaomi.com/ebayimg
/*	if (newUrl && newUrl.indexOf('i.ebayimg.com') !== -1 && type === 'show') {
		newUrl = returnStringReplaceResult(newUrl, 'i.ebayimg.com', 'cdn-platform.dianxiaomi.com/ebayimg', true);
	}*/
	//现在用回eBay原图，之前被替换的cdn-platform.dianxiaomi.com/ebayimg要还原回i.ebayimg.com
	if (newUrl && newUrl.indexOf('cdn-platform.dianxiaomi.com/ebayimg') !== -1 && type === 'show') {
		newUrl = returnStringReplaceResult(newUrl, 'cdn-platform.dianxiaomi.com/ebayimg', 'i.ebayimg.com', true);
	}
	if (newUrl && newUrl.indexOf('cf.shopee.com.my') !== -1 && type === 'show') {
		newUrl = returnStringReplaceResult(newUrl, 'cf.shopee.com.my', 's-cf-tw.shopeesz.com', true);
	}

	//保存的时候再还原回图片地址cf.shopee.com.my，这样只做显示，不做保存处理
	/*if (newUrl && newUrl.indexOf('cdn-platform.dianxiaomi.com/ebayimg') !== -1 && type === 'save') {
		newUrl = returnStringReplaceResult(newUrl, 'cdn-platform.dianxiaomi.com/ebayimg', 'i.ebayimg.com', true);
	}*/
    if (newUrl && newUrl.indexOf('s-cf-tw.shopeesz.com') !== -1 && type === 'save') {
		newUrl = returnStringReplaceResult(newUrl, 's-cf-tw.shopeesz.com', 'cf.shopee.com.my', true);
	}

	return newUrl;
};

// 格式化图片请求协议
function getFromatUrl(url){
    if(url){
        var flag = ['http://', 'https://', 'HTTP://', 'HTTPS://'].some(function (value) {
                return url.startWith(value);
            });

        if(!flag) {
			if(url.startWith('//')) {
                url = 'http:' + url;
			} else if (url.startWith('/')) {
                url = 'http:/' + url;
			} else {
                url = 'http://' + url;
			}
		}
    }

    return url;
}

function getTinyPicRealUrl(url){
	var realUrl = "";
	if(url){
		if(url.indexOf("http") == -1 && url.indexOf("HTTP") == -1){
			realUrl = getPicRealUrl(url);
		}else{
			realUrl = url;
		}
	}

	return realUrl;
}
/**
 * 客户端上传图片成功后回调处理
 * @param bucket
 * @param fileId
 * @param fullCid
 * @param fileName
 */
function clientPicCallBack(bucket, fileId, fullCid, fileName, isNeedTree, callBack){
	$.ajax({
		type:'POST',
		url: "album/clientPicCallBack.json",
		data:{
			"bucket":bucket,
			"fileId":fileId,
			"fullCid":fullCid,
			"fileName":fileName,
			"isNeedTree":isNeedTree
		},
		dataType:'json',
		async : true,
		success:function(data){
			if(data.code == 0){
				if(callBack){
					callBack(data.treeJson);
				}
			}else{
				$.fn.message({type:"error", msg:data.msg});
			}
		}
	});
}

/**
 * 判断字符串是否以某字符开头
 * @param str 要判断的字符
 * @return boolean true表示是以该字符开头的，false表示不是
 */
String.prototype.startWith = function (str) {
	if (!str || !this.length || str.length > this.length) {
		return false;
	} else if (this.substr(0,str.length) == str) {
		return true;
	}
	return false;
};

/**
 * 判断字符串是否以某字符结尾
 * @param str  要匹配的字符串，确认是否以该字符串结尾
 * @param isToLowerCase  是否不区分大小写，传true则不区分大小写，不传则需要区分
 * @return Boolean 如果是以str结尾的，那么返回true，否则返回false
 */
String.prototype.endWith = function (str, isToLowerCase) {
	/*
	* 比如例1、'abc'.endWith('c'); => true
	*    例2、'abc'.endWith('C'); => false
	*    例3、'abc'.endWith('C', true); => true
	* 这里的this='abc'，str='c'
	* 通过substring方法截取出当前字符串减去要匹配的字符串的长度之后的字符
	* 用上面的例子'abc'来说，长度3-1=2，截取字符串中下标2之后的（截取是会包含下标2所在的值，下标从0开始计算）
	* 截出来的值就是'c',用这个值判断是否等于str
	* */
	if (isToLowerCase) {
        return this.toLowerCase().substring(this.length - str.length) === str.toLowerCase();
    }
	return this.substring(this.length - str.length) === str;
};


// icon 添加Tooltip

/*
 * form不提交
 * add by fuyi 2015.5.6
 */
$(document).off('submit','form.doNotSubmit');
$(document).on('submit','form.doNotSubmit',function(){
	return false;
});


/*
* 输入框计数
* input外层class(enumerationDiv);
* $(#).iptToEnumeration(maxNum,isTruncation);
* maxNum/最大输入数
* isTruncation/是否截断 0或不传 不截断  1 截断
*
*
*/
(function($){
	$.fn.iptToEnumeration = function(maxNum,isTruncation){
		if(!isTruncation){
			isTruncation = 0;
		}
		var str = '<span class="enumeration myj-hide"><span class="num">0</span>/<span class="maxNum">'+maxNum+'</span></span>';
		this.closest('.enumerationDiv').append(str);
		this.closest('.enumerationDiv').css('position','relative');
		this.closest('.enumerationDiv').attr('maxNum',maxNum);
		if(isTruncation){
			this.attr('maxlength',maxNum);
		}
		var $span = $(this.closest('.enumerationDiv').find('.enumeration'));
		$span.css('position','absolute').css('right','5px').css('top','10px');
	}
})(jQuery);
$(document).on('keyup','.enumerationDiv input[type="text"]',function(){
	var maxNum = $(this).closest('.enumerationDiv').attr('maxNum'),
		num = $(this).val().length;
	$(this).closest('.enumerationDiv').find('.num').text(num);
});
$(document).on('focus','.enumerationDiv input[type="text"]',function(){
	$(this).css('padding-right','40px');
	$(this).closest('.enumerationDiv').find('.enumeration').show();
});
$(document).on('blur','.enumerationDiv input[type="text"]',function(){
	$(this).css('padding-right','12px');
	$(this).closest('.enumerationDiv').find('.enumeration').hide();
});


/*
* add by fuyi at 2016.3.19 with edit window alert and confirm
* myjAlert
* myjAlert.alert({'title':'aaa','content':'你现在测试的是alert!'})
* myjAlert.confirm({
	title: '提示', //弹层头部标题，可以不传，默认"提示"
    enter: '确定', //弹层确定按钮文案，可以不传，默认"确定"
    cancel: '取消', //弹层取消按钮文案，可以不传，默认"取消"
    typeHead: false, //是否不展示头部标题，true为不展示，不传或false默认展示
    modalWidth: 550, //弹层宽度，默认400
    isText: false, //是否展示纯文本，true为生成纯文本，不传或false默认生成html
    carriageReturnDetermin: true, //支持回车确定，true为支持，不传或false默认不支持
    content: '确认要一键完成吗？', //弹层内容
	callback: function (v) { //确认/取消按钮回调函数，v=true确认回调|false取消回调
		if (v) {

		} else {

		}
	}
});
*
*/
(function(win){
	var tips = {
			'title':'提示',
			'enter':'确定',
			'cancel':'取消',
			'close':'<button type="button" class="close"><span>×</span></button>'
		},
		isIE6 = !window.XMLHttpRequest,
		cssLoaded = false,
		isOpen = false,
		loadCss = function(){
			if(cssLoaded) return;
			var style = document.createElement('link');
			style.type = 'text/css';
			style.rel = 'stylesheet';
			document.getElementsByTagName('head')[0].appendChild(style);
			cssLoaded = true;
		};

	/*************************************对外提供的接口****************************************************/
	var dialog = function(opts){
		return new dialog.prototype.init(opts);
	};

	dialog.prototype = {
		constructor:dialog,
		init:function(opts){
			loadCss();
		},
		alert:function(opts){
			var _this = this;
			var set = extend({
				width: opts.modalWidth ? opts.modalWidth : 400,
				height:100
			},opts||{});
			if(isOpen) this.close();
			isOpen = true;
			this.doms = createElements(set);
			var spanTxt = document.createElement("span");

			if (opts.isText) { //如果isText为true，则内容按纯文本方式插入
				spanTxt.innerText = opts.content;
			} else { //如果isText为false，则内容按html节点方式插入
				spanTxt.innerHTML = opts.content;
			}
			this.doms.contentBox.appendChild(spanTxt);
			setCenter(this.doms);
			this.doms.btnEnter.onclick = function(){
				if (typeof opts.callback === 'function') {
					setTimeout(function () {
						opts.callback(true);
					}, 1);
				}
				_this.close();
			};
			if(opts.carriageReturnDetermin){
				this.doms.overlayer.focus();
				this.doms.overlayer.onkeydown = function(e){
					var key = window.event ? e.keyCode : e.which;
					if(+key === 13){
						if (typeof opts.callback === 'function') {
							setTimeout(function () {
								opts.callback(true);
							}, 1);
						}
						_this.close();
					}
				};
				this.doms.contentOuter.onkeydown = function(e){
					var key = window.event ? e.keyCode : e.which;
					if(+key === 13){
						if (typeof opts.callback === 'function') {
							setTimeout(function () {
								opts.callback(true);
							}, 1);
						}
						_this.close();
					}
				};
			}

			if(this.doms.contentTitle) this.doms.contentTitle.ondragstart = function(){ return false;};
			if(this.doms.close) this.doms.close.onclick = function(){
				if (typeof opts.callback === 'function') {
					setTimeout(function () {
						opts.callback(false);
					}, 1);
				}
                _this.close();
            };

			addEvent(window,'resize',function(){setCenter(_this.doms);})
		},
		confirm:function(opts){
			var _this = this;
			this.alert(opts);
			this.doms.btnBox.appendChild(this.doms.btnCancel);
			this.doms.btnCancel.onclick = function(){
				if (typeof opts.callback === 'function') {
					setTimeout(function () {
						opts.callback(false);
					}, 1);
				}
				_this.close();
			}
		},
		close:function(){
			var db = document.body;
			db.removeChild(this.doms.overlayer);
			db.removeChild(this.doms.contentOuter);
			isIE6 && db.removeChild(this.doms.overlayIframe);
			if(this.doms.contentTitle) this.doms.contentTitle.onmousedown = null;
			if(this.doms.close) this.doms.close = null;
			this.doms.btnEnter.onclick = this.doms.btnCancel.onclick = null;
			this.doms = null;
			isOpen = false;
		}
	};

	dialog.prototype.init.prototype = dialog.prototype;
	win.regMethod = function(scope,handler){
		return scope[handler]= dialog();
	};

	/**********************************私有方法*******************************************************/
	function extend(subClass,superClass){
		for(var key in superClass) subClass[key] = superClass[key];
		return subClass;
	}
	function createElements(opts){
		var db = document.body,
			h = Math.max(document.documentElement.clientHeight,document.body.offsetHeight),
			width = opts.width,
			height = opts.height,
			overlayer = null,
			overlayIframe = null,
			contentOuter = null,
			contentTitle = null,
			close = null,
			contentBox = null,
			btnBox = null,
			btnEnter = null,
			btnCancel = null;

		overlayer = createEl('<div class="modal-alert-overlayer" tabindex="0"></div>', db);
		overlayIframe = isIE6 && createEl('<iframe class="dialog_HideSelect" marginwidth="0" marginheight="0" align="top" scrolling="no" frameborder="0" src=""' +
			' style="position:absolute;top:0;left:0;width:100%;height:'+h+'px;filter: Alpha(Opacity=0);"></iframe>', db);
		contentOuter = createEl('<div class="modal-alert" style="width:'+width+'px;" tabindex="0"></div>', db);
		//是否有头部
		if(!(opts && opts.typeHead)){
			contentTitle = createEl('<div class="modal-alert-head"><h3>'+ (opts.title || tips.title) +'</h3></div>', contentOuter);
			close = createEl('<a class="modal-alert-btn-close" href="javascript:">'+ (opts.close || tips.close) +'</a>', contentTitle);
		}else{
			contentTitle = createEl('<div class="modal-alert-head"></div>', contentOuter);
		}
		contentBox = createEl('<div class="modal-alert-content"></div>', contentOuter);
		btnBox = createEl('<div class="modal-alert-footer"></div>', contentOuter);
		btnEnter = createEl('<button class="button btn-determine" type="button">'+ (opts.enter||tips.enter) +'</button>', btnBox);
		btnCancel = createEl('<button class="button btn-gray" type="button">'+(opts.cancel|| tips.cancel) +'</button>');

		return {
			overlayer: overlayer,
			overlayIframe: overlayIframe,
			contentOuter: contentOuter,
			contentTitle: contentTitle,
			close: close,
			contentBox: contentBox,
			btnBox: btnBox,
			btnEnter: btnEnter,
			btnCancel: btnCancel
		};
	}
	function createEl(str,parent){
		var div = document.createElement('div'),el;
		div.innerHTML = str;
		el = div.firstChild;
		return parent ? parent.appendChild(el) : el;
	}
	function setCenter(doms){
		if(doms && doms.contentOuter){
			var T = doms.contentOuter,w = T.offsetWidth,h = T.offsetHeight,timer = null;
			var dd = document.documentElement,W = dd.clientWidth,H = dd.clientHeight;
			T.style.left = (W-w)/2+'px';
			if(isIE6){
				window.onscroll = function(){
					if(timer) clearTimeout(timer);
					timer = setTimeout(function(){
						var t = Math.max(document.body.scrollTop,document.documentElement.scrollTop);
						T.style.top = (t+H-h)/2+'px';
					},100);
				}
			}
		}
	}

	function addEvent(el,type,fn){
		if(el.addEventListener != undefined){
			el.addEventListener(type,fn,false);
		}else if(el.attachEvent != undefined){
			el.attachEvent('on'+type,fn)
		}else{
			el['on'+type] = fn;
		}
	}
	function removeEvent(el,type,fn){
		if(el.removeEventListener != undefined){
			el.removeEventListener(type,fn,false);
		}else if(el.detachEvent != undefined){
			el.detachEvent('on'+type,fn);
		}else{
			el['on'+type] = function(){};
		}
	}

	function getElementPos(el){
		var x = 0,y=0;
		if(el.getBoundingClientRect){
			var pos = el.getBoundingClientRect();
			var d_root = document.documentElement,db = document.body;
			x = pos.left + Math.max(d_root.scrollLeft,db.scrollLeft) - d_root.clientLeft;
			y = pos.top + Math.max(d_root.scrollTop,db.scrollTop) - d_root.clientTop;
		}else{
			while(el != db){
				x += el.offsetLeft;
				y += el.offsetTop;
				el = el.offsetParent;
			}
		}
		return {
			x:x,
			y:y
		};
	}
	function ajax(opts){
		var xhr = null;
		var set = extend({
			type:'GET',
			url:''
		},opts||{});
		if(typeof window.XMLHttpRequest != 'undefined'){
			xhr = new window.XMLHttpRequest();
		}else{
			xhr = new ActiveXObject('MSXML2.XmlHttp.6.0');
		}
		xhr.open(set.type,set.url);
		xhr.onreadystatechange = function(){
			if(xhr.readyState == 4){
				if(xhr.status >= 200 && xhr.status <= 304 ){
					set.success && set.success(xhr.responseText);
				}else{
					set.failure && set.failure(xhr.status);
				}
			}
		};
		xhr.send(null);
	}
})(window);
regMethod(window,'myjAlert');


//获取设置图片真实宽高的方法
function getImgRealPX(url){
	var $IMG = new Image();
    $IMG.src = url;
    $IMG.onload = function(){
        var width = $IMG.width;
        var height = $IMG.height;
        var imgDom = $('body img[src="'+url+'"]');
        if(imgDom.length > 0){
            var text = width + ' X ' + height;
            imgDom.closest('.out').find('.imgSize').html(text).attr('data-size', width + ',' + height);
        }
    }
}
//（通用）获取设置图片真实宽高的方法
function generalGetImgRealPX(url,call){
    var $i = new Image();
    $i.src = url;
    $i.onload = function(){
        call && call({w:$i.width,h:$i.height});
    };
}
//获取当前location
var gitWinLocHref = function(){
	var location = (window.location.href).split('/');
	var basePath = location[0]+'//'+location[2]+'/';
	return basePath;
};
//获取url所带参数
var getQueryString = function(name){
	var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
	var r = window.location.search.substr(1).match(reg);
	if(r!=null)return  r[2]; return null;
};
// 获取url所有参数
var getQueryData = function(){
    var r = window.location.href.split('?')[1],
        obj = {};
    if(r) {
    	r.split('&').forEach(function (value) {
    		var arr = value.split('=');
            obj[arr[0]] = arr[1];
		});
	}
	return r ? obj : null;
};
//获取传入的url所带参数
var getUrlParameter = function(url, name){
	var r = null,
		urlArr = url.indexOf('?') !== -1 ? url.split('?') : [];

	if(urlArr && urlArr.length > 1){
		var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
		r = urlArr[1].match(reg);
	}
	if(r != null) return r[2]; return null;
};
//获取17传入的url所带参数 #
var get17UrlParameter = function(url, name){
	var r = null;
	if(url && url.length > 1){
		var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
		r = url.match(reg);
	}
	if(r != null) return r[2]; return null;
};
//判断obj是不是空的 空的返回true,不空返回false;
var isEmptyObject = function(e){
	var t;
	for(t in e)
		return !1;
	return !0;
};
//产品列表sku展开收起共用
$(document).on('click','.productListSkuShow',function(){
	var value = $(this).attr('data-value'),
		td = $(this).closest('td'),
		table = $(this).closest('table');
	if(!+value){//==0 状态为隐藏 方案为‘+ 展开SKU’
		/*table.find('tr.otherSkuTr').hide();
        table.find('a.productListSkuShow').attr('data-value',0).html('+ 展开');*/
		td.find('tr.otherSkuTr').show();
		$(this).attr('data-value',1).html('- 收起');
	}else{//==1 状态为隐藏 方案为‘- 收起SKU’
		td.find('tr.otherSkuTr').hide();
		$(this).attr('data-value',0).html('+ 展开');
	}
});

/*
* 设置文本的光标位置到最后面
* 设置contenteditable属性的可编辑节点，重新赋值内容后光标会跑到前面去，需要把光标设置到最后面
* */
var setSelectionFn = function (obj) {
    var s = window.getSelection(), //获取当前页面上光标所在位置对象
        r = document.createRange(); //创建一个光标对象

    //指定选择某段文字从哪开始，第一个参数是需要光标选中的节点，第二个参数是设置光标起始选中值
    r.setStart(obj, 1); //好像只能设置0和1，设置其他值就报错了，setStart和setEnd都设置0的话光标会在节点的开头，都设置1的话就会到结尾
    //指定选择某段文字从哪结束，第一个参数是需要光标选中的节点，第二个参数是设置光标结束选中值
    r.setEnd(obj, 1); //好像只能设置0和1，设置其他值就报错了，setStart和setEnd都设置0的话光标会在节点的开头，都设置1的话就会到结尾
    s.removeAllRanges(); //移除当前页面上所有的光标
    s.addRange(r); //新添加一个光标，把创建的光标对象添加进去
};
/*
* 设置文本的最大可输入字符限制
* 设置contenteditable属性的可编辑节点，没法和输入框一样限制最大可输入字符长度，需要单独截取处理
* */
var setTextMaxLenFn = function ($obj, val) {
	var maxLen = $obj.attr('maxlength');
	if (maxLen && val.length > +maxLen) {
		val = val.substring(0, +maxLen);
	}
	$obj.text(val);
};

/****价格类输入框限制输入数字、负数、小数点以外的字符****/
function  validateNumeric(strValue) {
	var objRegExp  =  /(^-?\d\d*\.\d{0,2}$)|(^-?\d\d*$)/;
	return objRegExp.test(strValue);
}

//onkeyup事件
function clearNoNum(obj){
	var ipt = $(obj);
	if(!validateNumeric(ipt.val()))
	{
        ipt.val(ipt.val().replace("-.","%$%").replace(/\-\./g,"").replace("%$%","-"));
        ipt.val(ipt.val().replace(".-","$#$").replace(/\.\-/g,"").replace("$#$","."));
        ipt.val(ipt.val().replace(/[^-\d.]/g,"")); //清除"数字"和"."以外的字符
        ipt.val(ipt.val().replace(/^\./g,"")); //验证第一个字符是数字而不是
        ipt.val(ipt.val().replace(".","$#$").replace(/\./g,"").replace("$#$","."));//只保留第一个. 清除多余的
        ipt.val(ipt.val().replace("-","$%$").replace(/\-/g,"").replace("$%$","-"));//只保留第一个- 清除多余的
        ipt.val(ipt.val().replace(/\d{1,}-|\d{1,}\.\d{1,2}-/,""));//不能在数字后面输入-
        ipt.val(ipt.val().replace(/^(-)?(\d+)\.(\d\d).*$/,'$1$2.$3')); //只能输入两个小数
	}
}
/****价格类输入框限制输入end****/
/****价格类输入框限制输入负数可以输小数点，保留一位小数****/
var clearNoNumAndMinusOne = function (obj) {
	var ipt = $(obj);
	if(!validateNumMinusOne(ipt.val()))
	{
		ipt.val(ipt.val().replace(/[^\d.]/g, '')); //清除"数字"和"."以外的字符
		ipt.val(ipt.val().replace(/^\./g, '')); //验证第一个字符是数字而不是
		ipt.val(ipt.val().replace('.', '$#$').replace(/\./g, '').replace('$#$', '.'));
		ipt.val(ipt.val().replace(/^(\d+)\.(\d).*$/, '$1.$2')); //只能输入两个小数
	}
};
var validateNumMinusOne = function(strValue) {
    var objRegExp  =  /(^\d\d*\.\d{0,1}$)|(^\d\d*$)/;
    return objRegExp.test(strValue);
};
/****价格类输入框限制输入负数可以输小数点，保留一位小数END****/
/****价格类输入框限制输入负数可以输小数点，保留两位小数****/
var clearNoNumAndMinus = function (obj, type) {
	var ipt = $(obj),
		isText = type === 'text',
		val = isText ? ipt.html() : ipt.val();
	if(!validateNumMinus(val)) {
		val = val.replace(/[^\d.]/g, ''); //清除"数字"和"."以外的字符
		val = val.replace(/^\./g, ''); //验证第一个字符是数字而不是
		val = val.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
		val = val.replace(/^(\d+)\.(\d\d).*$/, '$1.$2'); //只能输入两个小数

		if (!isText) {
			ipt.val(val);
        }
	}
	if (isText) {
		setTextMaxLenFn(ipt, val);
		//设置contenteditable属性的可编辑节点，重新赋值内容后光标会跑到前面去，需要把光标设置到最后面
		setSelectionFn(obj);
	}
};

var validateNumMinus = function(strValue) {
    var objRegExp  =  /(^\d\d*\.\d{0,2}$)|(^\d\d*$)/;
    return objRegExp.test(strValue);
};
/****价格类输入框限制输入负数可以输小数点，保留两位小数END****/
/****价格类输入框限制输入负数可以输小数点，保留小数点后三位****/
var clearNoNumAndMinusDecimal3 = function (obj, type) {
	var ipt = $(obj),
		isText = type === 'text',
		val = isText ? ipt.html() : ipt.val();
	if(!validateNumMinusDecimal3(val)) {
		val = val.replace(/[^\d.]/g, ''); //清除"数字"和"."以外的字符
		val = val.replace(/^\./g, ''); //验证第一个字符是数字而不是
		val = val.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
		val = val.replace(/^(\d+)\.(\d\d\d).*$/, '$1.$2'); //只能输入两个小数
		if (!isText) {
			ipt.val(val);
		}
	}
	if (isText) {
		setTextMaxLenFn(ipt, val);
		//设置contenteditable属性的可编辑节点，重新赋值内容后光标会跑到前面去，需要把光标设置到最后面
		setSelectionFn(obj);
	}
};
var validateNumMinusDecimal3 = function(strValue) {
    var objRegExp  =  /(^\d\d*\.\d{0,3}$)|(^\d\d*$)/;
    return objRegExp.test(strValue);
};
/****价格类输入框限制输入负数可以输小数点，保留小数点后三位END****/
/****价格类输入框限制输入负数可以输小数点，保留小数点后4位****/
var clearNoNumAndMinusDecimalLimit4 = function (obj) {
	var ipt = $(obj);
	if(!validateNumMinusDecimalLimit4(ipt.val()))
	{
		ipt.val(ipt.val().replace(/[^\d.]/g, '')); //清除"数字"和"."以外的字符
		ipt.val(ipt.val().replace(/^\./g, '')); //验证第一个字符是数字而不是
		ipt.val(ipt.val().replace('.', '$#$').replace(/\./g, '').replace('$#$', '.'));
		ipt.val(ipt.val().replace(/^(\d+)\.(\d\d\d\d).*$/, '$1.$2')); //只能输入两个小数
	}
};
var validateNumMinusDecimalLimit4 = function(strValue) {
	var objRegExp  =  /(^\d\d*\.\d{0,4}$)|(^\d\d*$)/;
	return objRegExp.test(strValue);
};
/****价格类输入框限制输入负数可以输小数点，保留小数点后4位END****/
/****价格类输入框限制输入负数可以输小数点，保留小数点后5位****/
var clearNoNumAndMinusDecimal5 = function (obj) {
	var ipt = $(obj);
	if(!validateNumMinusDecimal5(ipt.val()))
	{
		ipt.val(ipt.val().replace(/[^\d.]/g, '')); //清除"数字"和"."以外的字符
		ipt.val(ipt.val().replace(/^\./g, '')); //验证第一个字符是数字而不是
		ipt.val(ipt.val().replace('.', '$#$').replace(/\./g, '').replace('$#$', '.'));
		ipt.val(ipt.val().replace(/^(\d+)\.(\d\d\d\d\d).*$/, '$1.$2')); //只能输入两个小数
	}
};
var validateNumMinusDecimal5 = function(strValue) {
    var objRegExp  =  /(^\d\d*\.\d{0,5}$)|(^\d\d*$)/;
    return objRegExp.test(strValue);
};
/****价格类输入框限制输入负数可以输小数点，保留小数点后5位END****/
/****价格类输入框限制输入小数点可以输负数****/
var clearNoNumAndFloat = function (obj) {
    var ipt = $(obj);
    if(!validateNumFloat(ipt.val()))
    {
        ipt.val(ipt.val().replace(/[^-\d]/g, '')); //清除"数字"和"."以外的字符
        ipt.val(ipt.val().replace('-', '$%$').replace(/\-/g, '').replace('$%$', '-'));
        ipt.val(ipt.val().replace(/\d{1,}-|\d{1,}-\d{1,}/, ''));
    }
};
var validateNumFloat = function(strValue) {
    var objRegExp  =  /^-?\d\d*$/;
    return objRegExp.test(strValue);
};
/****价格类输入框限制输入小数点可以输负数END****/
/****价格类输入框4位限制输入****/
function clearNoNumFour(obj){
    var ipt = $(obj);
    if(!validateNumeric(ipt.val()))
    {
        ipt.val(ipt.val().replace(/[^\d.]/g,"")); //清除"数字"和"."以外的字符
        ipt.val(ipt.val().replace(/^\./g,"")); //验证第一个字符是数字而不是
        ipt.val(ipt.val().replace(/\.{2,}/g,".")); //只保留第一个. 清除多余的
        ipt.val(ipt.val().replace(/\d{7,}./g,".")); //只保留第一个. 清除多余的
        ipt.val(ipt.val().replace(".","$#$").replace(/\./g,"").replace("$#$","."));
        ipt.val(ipt.val().replace(/^(\-)*(\d+)\.(\d\d\d\d).*$/,'$1$2.$3')); //只能输入四个小数
    }
}
/****价格类输入框4位限制输入End****/

/****价格类输入框自定义限制输入****/
/**
 * type 输入框形式 不为input时传'text'，通过.html()赋值
 * decimal 保留几位小数，默认2位
 * max 价格最大值，默认不作限制
 * **/
function clearNoNumAndMinusSetting(obj, decimal, max, type) {
	var ipt = $(obj),
		isText = type === 'text',
		decimal = decimal || 2,
		val = isText ? ipt.html() : ipt.val();

	if (!validateNumMinusSetting(val, decimal)) {
		val = val.replace(/[^\d.]/g, ''); //清除"数字"和"."以外的字符
		val = val.replace(/^\./g, ''); //验证第一个字符是数字而不是
		val = val.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');

		var decimalRegStr = '^(\\d+)\\.(';

		for (var i = 0; i < +decimal; i++) {
			decimalRegStr += '\\d';
		}
		decimalRegStr += ').*$';

		var decimalReg = new RegExp(decimalRegStr);

		val = val.replace(decimalReg, '$1.$2'); // 保留decimal位小数

		if (!isText) {
			ipt.val(val);
		}
	}

	if (max && typeof +max === 'number') {
		if (+val > max) val = max;

		if (!isText) {
			ipt.val(val);
		}

	}

	if (isText) {
		setTextMaxLenFn(ipt, val);
		//设置contenteditable属性的可编辑节点，重新赋值内容后光标会跑到前面去，需要把光标设置到最后面
		setSelectionFn(obj);
	}
}
/****价格类输入框自定义限制输入 end****/

var validateNumMinusSetting = function(strValue, decimal) {
	var objRegExpStr = '(^\\d\\d*\\.\\d{0,' + decimal + '}$)|(^\\d\\d*$)'

	var objRegExp =  new RegExp(objRegExpStr);
	return objRegExp.test(strValue);
};

//数字类输入框限制最大值
var clearNoNumMaxValue = function (obj, maxVal, isTrue) { //obj=输入框对象，maxVal=最大值，不传默认9999999.99,isTrue=是否支持负数
	var $obj = $(obj),
		val = $obj.val();

	if(val){
		if(!isTrue && isNaN(val)){ //如果支持负数则不验证，输入框的值如果不是数字则转成数字，默认小数点2位
			clearNoNumAndMinus($obj);
			val = $obj.val();
		}
		if(!maxVal || isNaN(maxVal)) maxVal = 9999999.99; //不传默认9999999.99
		if(isTrue && val < 0){
			if(!(+val > +(-maxVal))) $obj.val(-maxVal); //如果输入框的值大于最大值，则赋值最大值
			return;
		}
		if(+val > +maxVal) $obj.val(+maxVal); //如果输入框的值大于最大值，则赋值最大值
	}
};

/****重量类进行增减的输入验证 可以输入负数和小数，并保留小数点后3位****/
/** 参数： notAllowMinus 不允许输入负数，默认false允许负数， 传true则不允许**/
var clearNoNumDecimal3 = function(obj, notAllowMinus){
    var ipt = $(obj);
    if(!validateNumeric3(ipt.val()))
    {
        ipt.val(ipt.val().replace("-.","%$%").replace(/\-\./g,"").replace("%$%","-"));
        ipt.val(ipt.val().replace(".-","$#$").replace(/\.\-/g,"").replace("$#$","."));
        ipt.val(ipt.val().replace(/[^-\d.]/g,"")); //清除"数字"和"."以外的字符
        ipt.val(ipt.val().replace(/^\./g,"")); //验证第一个字符是数字而不是
        // ipt.val(ipt.val().replace(/\d{7,}./g,"."));
        ipt.val(ipt.val().replace(".","$#$").replace(/\./g,"").replace("$#$","."));//只保留第一个. 清除多余的
        ipt.val(ipt.val().replace("-","$%$").replace(/\-/g,"").replace("$%$","-"));//只保留第一个- 清除多余的
        ipt.val(ipt.val().replace(/\d{1,}-|\d{1,}\.\d{1,2}-/,""));//不能在数字后面输入-
        ipt.val(ipt.val().replace(/^(-)?(\d+)\.(\d\d\d).*$/,'$1$2.$3')); //只能输入三位小数
    }
	if(notAllowMinus){
		ipt.val(ipt.val().replace(/-/g, ''));
	}
};
function  validateNumeric3(strValue) {
	var objRegExp  =  /(^-?\d\d*\.\d{0,3}$)|(^-?\d\d\d*$)/;
	return objRegExp.test(strValue);
}
/****重量类进行增减的输入验证 可以输入负数和小数，并保留小数点后3位end****/

/****重量类进行增减的输入验证 可以输入负数和小数，并保留小数点后2位****/
var clearNoNumDecimal2 = function(obj){
    var ipt = $(obj);
    if(!validateNumeric2(ipt.val()))
    {
        ipt.val(ipt.val().replace("-.","%$%").replace(/\-\./g,"").replace("%$%","-"));
        ipt.val(ipt.val().replace(".-","$#$").replace(/\.\-/g,"").replace("$#$","."));
        ipt.val(ipt.val().replace(/[^-\d.]/g,"")); //清除"数字"和"."以外的字符
        ipt.val(ipt.val().replace(/^\./g,"")); //验证第一个字符是数字而不是
        // ipt.val(ipt.val().replace(/\d{7,}./g,"."));
        ipt.val(ipt.val().replace(".","$#$").replace(/\./g,"").replace("$#$","."));//只保留第一个. 清除多余的
        ipt.val(ipt.val().replace("-","$%$").replace(/\-/g,"").replace("$%$","-"));//只保留第一个- 清除多余的
        ipt.val(ipt.val().replace(/\d{1,}-|\d{1,}\.\d{1,2}-/,""));//不能在数字后面输入-
        ipt.val(ipt.val().replace(/^(-)?(\d+)\.(\d\d).*$/,'$1$2.$3')); //只能输入三位小数
    }
};
function  validateNumeric2(strValue) {
	var objRegExp  =  /(^-?\d\d*\.\d{0,2}$)|(^-?\d\d*$)/;
	return objRegExp.test(strValue);
}
/****重量类进行增减的输入验证 可以输入负数和小数，并保留小数点后2位end****/

/****非中文输入框限制输入****/
function  validateCJK(strValue) {
    var objRegExp  =  /[\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF]/;
    return objRegExp.test(strValue);
}

//onkeyup事件
function clearCJK(obj){
    var ipt = $(obj);
    if(validateCJK(ipt.val()))
    {
        ipt.val(ipt.val().replace(/[\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF]/g,"")); //清除"数字"和"."以外的字符
    }
}
/****非中文输入框限制输入end****/
/****字母和数字输入框限制输入****/
function  validateCN(strValue) {
	var objRegExp  =  /[^a-zA-Z0-9]*$/;
	return objRegExp.test(strValue);
}

//onkeyup事件
function validateInCN(obj){
	var ipt = $(obj);
	if(validateCN(ipt.val()))
	{
		ipt.val(ipt.val().replace(/[^a-zA-Z0-9]/g,"")); //清除"数字"和"字母"以外的字符
	}
}
/****字母和数字输入框限制输入end****/

/****限制输入除数字、字母、空格、汉字之外的其它字符****/
var clearNoSpecialCharacter = function (obj){
	var $ipt = $(obj),
		val = $ipt.val();
	if(validateSpecialCharacter(val)) {
		$ipt.val(val.replace(/[^a-zA-Z0-9\u4e00-\u9fa5\s]+/g,'')); //清除数字、字母、空格和汉字以外的字符
	}
};
var validateSpecialCharacter = function (strValue) {
	var objRegExp = /[^a-zA-Z0-9\u4e00-\u9fa5\s]+/g;
    return objRegExp.test(strValue);
};
/****字限制输入除数字、字母、空格、汉字之外的其它字符end****/

/****限制输入除数字、字母、-、_之外的其它字符****/
var clearNoSpecialCharacterBar = function (obj){
	var $ipt = $(obj),
		val = $ipt.val();
	if(validateSpecialCharacterBar(val)) {
		$ipt.val(val.replace(/[^A-Za-z0-9-\_\-]+/,'')); //清除数字、字母、空格和汉字以外的字符
	}
};
var validateSpecialCharacterBar = function (strValue) {
	var objRegExp = /[^A-Za-z0-9-\_\-]+/;
	return objRegExp.test(strValue);
};
/****限制输入除数字、字母、-、_之外的其它字符end****/


//清除字符串中间多余的连续空格
var clearStringMiddleSpaceFn = function (obj) {
	var $ipt = $(obj);

	$ipt.val(getClearStringMiddleSpaceFn($ipt.val()));//清除中间多余的连续空格
};

//得到清除字符串中间多余的连续空格后的结果
var getClearStringMiddleSpaceFn = function (strValue) {
	var spaceErgExp = /\s+/g;

	if (strValue && spaceErgExp.test(strValue)) return strValue.replace(spaceErgExp, ' ');//清除中间多余的连续空格
	return strValue;
};

/****整数类输入框限制输入****/
//onkeyup事件
function clearMistakeNumber(obj, type){
	var ipt = $(obj),
		isText = type === 'text',
		val = isText ? ipt.html() : ipt.val();
	var objRegExp = /[^\d]/;
	if(objRegExp.test(val)){
		val = val.replace(/[^\d]/g, '');
		if (!isText) {
			ipt.val(val);
        }
	}
	if (isText) {
		setTextMaxLenFn(ipt, val);
		//设置contenteditable属性的可编辑节点，重新赋值内容后光标会跑到前面去，需要把光标设置到最后面
		setSelectionFn(obj);
	}
}
/****整数类输入框限制输入end****/

/****电话类输入框限制输入****/
//onkeyup事件
function clearPhoneFormat(obj){
	var ipt = $(obj);
	var objRegExp  =  /[^0-9,-]/;
	if(objRegExp.test(ipt.val())){
		ipt.val(ipt.val().replace(/[^0-9,-]/g,""));
	}
}
/****电话类输入框限制输入end****/

/** 价格验证 start**/
function verifyPrice(str){
	if(str.match(/^(:?(:?\d+.\d+)|(:?\d+))$/)) return true;
	else false;
}
/** 价格验证 end**/

//二级下拉菜单 阻止主按钮点击关闭下拉层
$(document).off('click','.dropdown-menu .removefromcart');
$(document).on('click','.dropdown-menu .removefromcart',function(e){
	e.stopPropagation();
});

/**字符串与unicode互转**/
//to code
function strToUc(str) {
	if (String(str)) {
		str = String(str);
		var st, t, i;
		st = '';
		for (i = 1; i <= str.length; i ++){
			t = str.charCodeAt(i - 1).toString(16);
			if (t.length < 4)
				while(t.length <4)
					t = '0'.concat(t);
			t = t.slice(2, 4).concat(t.slice(0, 2));
			st = st.concat(t);
		}
		return(st.toUpperCase());
	}else {
		return('');
	}
}
//to str
function ucToStr(str) {
	if (str) {
		var st, t, i;
		st = '';
		for (i = 1; i <= str.length/4; i ++){
			t = str.slice(4*i-4, 4*i-2);
			t = str.slice(4*i-2, 4*i).concat(t);
			st = st.concat('%u').concat(t);
		}
		st = unescape(st);
		return(st);
	}else{
		return('');
	}
}
/**字符串与unicode互转 end**/

/*
* localstorage set and get
* add 2016.8.19 fuyi
*
* 设(string)     myjStorage.set(key,string)()
* 设(obj)        myjStorage.objSet(key,obj)()
* 取(string)     myjStorage.get(key)()
* 取(obj)        myjStorage.objGet(key)()
* 查             myjStorage.storageObj()  返回整个storageObj对象
* 删             myjStorage.remove(key)()  销毁storageObj中的key
* 查Key          myjStorage.getKeyName()()  返回arr storageObj中的key
* 时间比较       myjStorage.dateDiff(DateOne,DateTwo)   日期格式 YYYY/MM/dd 返回Number
*
* use key :
*           userId_indexChart （index图表操作）
*           userId_needNoticeId
*           userId_globalWarehoseZ
*           userId_globalPairWarehoseZ
*           userId_offSmallYellowUser（用户订单页可关闭小黄条）
*           createRUCT (index右侧上面广告关闭时间)
*           createRDCT (index右侧下面广告关闭时间)
*           wish_listImgType_add (wish变种图是否显示)
*           t1001(用户列表搜索type)t_userId:{wish:0or1;purWare:0or1;} 产品wish  采购和仓库列表 purWare
*			t1002(用户处理错误订单){t_userId:date}(hhj)
*           t1003(用户是否点击分批次发货)
*           t1007(扫描校验是否启用只校验，不打印)
*           t1007_sku / t1007_item_single / t1007_items_single / t_1007_item_batch / t_1007_items_batch(扫描校验包裹类型/扫描校验单品单数（单个）/单品多数（单个）/ 单品单数（批量）/ 单品多数（批量） )
*           t1007_print_design（扫描立即打印设置）
*           t1008(扫描发货)
*           wave（波次)
*           wave_create_storage/波次生成上一次选的仓库Id
*         	wave_manage_storage/波次管理上一次选的仓库Id
*         	wave_twice_sort_sku_type/二次分拣上一次所选的扫描类型
*       	wave_scan_sku_type/扫描包装上一次所选的扫描类型
*           scanShipWeightUnit (波次扫描出库 重量记忆)
*           img_resize(图片改尺寸用户上次用值){min:number,set:number}
*           init_repository (初始化仓库选中值){type:Array}
*           allocated_has_moduleName(记录用户在待打单-有货所选的板块 normal:常规板块；group:分组板块)
*			stat_01A(记录数据模块-各个子版块的统计图维度选择和币种选择和统计图类型)
*			wishBatchGuide(记录用户是否进入过wish批量编辑并点击)
*		    userId_wishIsPromotedTip(记录用户删除加钻提示小黄条)
*		    userId_voicePlayback(记录用户浏览器播放方式)
* 			orderPageSize_userId(记录用户订单列表分页条数)
* 			orderOtherPageSize_userId(记录用户订单其它模块分页条数)
* 			t1009_userId(平台刊登自定义翻译)
*/
var myjStorage = {
    storageObj : function(){
        return window.localStorage;
    },
    get : function(key){
        return function(){
            return this.myjStorage.storageObj().getItem(key);//this (window)
        };
    },
	objGet : function(key){
		return function(){
			return JSON.parse(this.myjStorage.storageObj().getItem(key));//this (window)
		};
	},
    set : function(key,value){
		return function(){
			this.myjStorage.storageObj().setItem(key,value);
		}
	},
	objSet : function(key,value){
		return function(){
			this.myjStorage.storageObj().setItem(key,JSON.stringify(value));
		}
	},
    remove : function(key){
        return function(){
            this.myjStorage.storageObj().removeItem(key);
        }
    },
    dateDiff : function(DateOne, DateTwo){
		DateOne = DateOne ? DateOne.replace(/-|\//g, '') : '';
		DateTwo = DateTwo ? DateTwo.replace(/-|\//g, '') : '';
		var cha = 1;
		if(DateOne == DateTwo){
			cha = 0;
		}
        //return Math.abs(cha);
        return cha;
    },
    getKeyName : function(){
        return function(){
            var arr = [];
            $.each(this.myjStorage.storageObj(),function(keyName,value){
                arr.push(keyName);
            });
            return arr;
        }
    }

};
/***localstorage set and get***/

//类目搜索（单级内）
$(document).off('keyup','.categoryChooseOutDiv .serch input[type="text"]');
$(document).on('keyup','.categoryChooseOutDiv .serch input[type="text"]',function(){
    var searchValue = $.trim($(this).val()),
		forDivCla = $(this).data('for'), // 增加 data-for 属性，用于自定义获取列表
        $list = $(this).closest('.categoryChooseInDiv').find(forDivCla ? forDivCla: 'div.categoryDiv'),
        html = '',
		newStrArr = []; //根据查询字段把转了小写之后的数据字段进行分割
    if(searchValue){
        $list.addClass('myj-hide');
        $.each($list,function (i,j) {
            html = $(j).find('.categoryNames').text();
            $(j).attr('content',html);
            newStrArr = html.toLowerCase().split(searchValue.toLowerCase());
            if(newStrArr && newStrArr.length > 1){
                $(j).removeClass('myj-hide').find('.categoryNames').html(returnSearchContentMarkedRedResult(html,searchValue));
			}
        });
    }else{
        $list.removeClass('myj-hide');
        $.each($list,function (i,j) {
            $(j).find('.categoryNames').html($(j).attr('content'));
        });
    }
});
//搜索内容标红方法
var returnSearchContentMarkedRedResult = function (searchOriginalCon,searchCon) {
	if(!searchOriginalCon || !searchCon) return searchOriginalCon;
	var toLowerCaseCategoryNames = searchOriginalCon.toLowerCase(),//转小写之后的数据字段
		toLowerCaseVal = searchCon.toLowerCase(),//转小写之后的查询字段
		newStrArr = toLowerCaseCategoryNames.split(toLowerCaseVal), //根据查询字段把转了小写之后的数据字段进行分割
		joinStr = '',//用来拼接转了小写之后的数据字段，主要是为了截取原数据字段中的内容
		dataStr = '',//用来接收截取出来的原数据字段内容
		endStr = '',//用来接收拼接完之后的原数据字段
		length = newStrArr.length;
	for(var i = 0; i < length; i++){
		dataStr = searchOriginalCon.substring(joinStr.length, joinStr.length + newStrArr[i].length);//这里每次循环获取到的内容就是没有转小写的原数据字段
		joinStr += newStrArr[i]; //这里把当前循环数组下标中转了小写的内容拼接起来
		/*这里把上面获取的没转小写的内容拼接上要查询的内容,然后把要查询的内容用标签包起来字体变红色
		 * htmls.substring(joinStr.length,joinStr.length+toLowerCaseVal.length)获取当前循环内容长度到当前循环内容长度加上查询内容长度之间的内容，这个内容就是没转小写的要查询内容
		 */
		if(i === (length-1)){
			endStr += dataStr;
		}else{
			endStr += dataStr + '<span class="f-red">' + searchOriginalCon.substring(joinStr.length,joinStr.length+toLowerCaseVal.length) + '</span>';
		}
		joinStr += toLowerCaseVal; //把上面拼接的循环内容在加上要查询的内容,用来下次循环的时候截取下一段内容
	}
	return endStr;

};

/*
* 产品订单显示条目数
*
* objNode，判断是否为order用Table
*/
function showSelCheckboxNum(obj,objNode){
	var $id = $(obj).attr('selIptId'),
		$table = $(obj).closest('table'),
		$selectAll = $table.find('[selIptId="selectAll"]'),
		tableCeil = $(obj).closest('body').find('#ceilingDiv').find('#selectedData'),	// 选中条数显示的容器
		normalInput = $table.find('input[datename="showdate"]'),	// 列表商品中的复选框
		inputNumtwo = normalInput.length,		// 选中的商品的数量
		numtd = 0,
		checkedNum = '',
		selectAllState = 0;

	// th个数
	numtd = $table.children("thead").children('tr:first-child').children('th').length;
	var $hasColspanTh = $table.children('thead').children('tr:first-child').children('th[colspan]');
	$hasColspanTh.each(function(){
		var colspan = $(this).attr('colspan');
		if(+colspan > 1) numtd += colspan - 1;
	});
	if(+numtd === 0) numtd = 9; //兼容不规范列表

	if ($id === 'selectAll'){ //判断全选
		if($selectAll.is(':checked')){
			normalInput.prop('checked',true);
			selectAllState = 1;
		}else{
			normalInput.prop('checked',false);
		}
	}
	// 选中的商品的复选框的数量
	checkedNum = normalInput.filter(':checked').length;
	if (inputNumtwo && checkedNum && inputNumtwo === checkedNum) { //判断全选选中
		if (!$selectAll.is(':checked')){
			$selectAll.prop('checked', true);
			selectAllState = 1;
		}
	} else {
		if ($selectAll.is(':checked')) {
			$selectAll.prop('checked', false);
		}
	}
    var $showSelCheckboxNum = $table.find('tr[selId="showSelCheckboxNum"]'),
        $initialize = tableCeil.find('.initialize');
	if(checkedNum > 0){ //添加小黄条
		if (!+$showSelCheckboxNum.length){
			$showSelCheckboxNum = $('<tr class="show-sel-check-num showSelCheckboxNum"' +
				' selId="showSelCheckboxNum" id="showSelCheckboxNum">' +
				'<td class="check-num-con" colspan="'+numtd+'">' +
				'<span class="initialize"><span class="check-num-in showSelCheckboxNumIn"></span>' +
				'<span class="ctrl-selection ctrlSelection"></span></span></td></tr>');
			$selectAll.closest('tr').after($showSelCheckboxNum);

			$initialize = $('<span class="initialize">&nbsp;&nbsp;已选中<span class="checkedNum"></span>条数据<span class="ctrlSelection"></span></span>');
			tableCeil.html($initialize);
		}
		$initialize.find('.checkedNum').html(checkedNum);
		$showSelCheckboxNum.find('span.showSelCheckboxNumIn').html('已选中'+checkedNum+'条数据');
		if($selectAll.is(':checked')){ //再次判断全选是否选中
			selectAllState = 1;
		}
		if(objNode === 'order'){
			ctrSelectionNum(selectAllState, $showSelCheckboxNum, tableCeil);
		}
		if(objNode === 'orderUpdate'){
			ctrUpdateSelectionNum(selectAllState);
		}

		if(objNode === 'purchase'){ //采购建议
			$('input.topSupplier').prop('checked', $selectAll.is(':checked'));
			purchasePlatNum(selectAllState);
		}

        //仓库管理-仓库清单-筛选商品
		if(objNode === 'wareProduct'){
			showPageCountMethod(selectAllState);
		}
	}else{
        $showSelCheckboxNum.remove();
		tableCeil.empty();

		if(objNode === 'purchase'){ //采购建议
			$('input.topSupplier').prop('checked', $selectAll.is(':checked'));
			clearOriginMethod();
		}
	}
    var $ceilingTypePlaceholderDiv = $('.ceilingTypePlaceholderDiv');
    if($ceilingTypePlaceholderDiv.length){
        $ceilingTypePlaceholderDiv.css('height', $table.children('thead').height() + 'px');
    }
}

/*
* 物流追踪显示条目数
*
*/
function showSelCheckboxTrackNum(obj){
    var $id = $(obj).attr('selIptId'),
        $table = $(obj).closest('table'),
        $selectAll = $table.find('[selIptId="selectAll"]'),
        tableCeil = $(obj).closest('body').find('#ceilingDiv').find('#selectedData'),
        normalInput = $table.find('input[datename = "showdate"]'),
        inputNumtwo = normalInput.length,
        numtd = $table.find("tr").eq(2).find('td').length,
        checkedNum = '',
        selectAllState = 0;
    if(numtd < 8){
        numtd = 12;
    }
    var $newStr = $('<tr class="show-sel-check-num showSelCheckboxNum" selId="showSelCheckboxNum"  id="showSelCheckboxNum">' +
        '<td class="check-num-con" colspan="'+numtd+'">' +
        '<span class="initialize"><span class="check-num-in showSelCheckboxNumIn"></span>' +
        '<span class="ctrl-selection ctrlSelection"></span></span></td></tr>'),
        $ceilStr = $('<span class="initialize">&nbsp;&nbsp;已选中<span class="checkedNum"></span>条数据<span class="ctrlSelection"></span></span>');
    if ($id == 'selectAll'){ //判断全选
        if($selectAll.is(':checked')){
            normalInput.prop('checked',true);
            selectAllState = 1;
        }else{
            normalInput.prop('checked',false);
        }
    }
    checkedNum = $table.find('input[datename = "showdate"]:checked').length;
    if (inputNumtwo == checkedNum) { //判断全选选中
        if (!$selectAll.is(':checked')){
            $selectAll.prop('checked', true);
            selectAllState = 1;
        }
    } else {
        if ($selectAll.is(':checked')) {
            $selectAll.prop('checked', false);
        }
    }
    if(checkedNum > 0){ //添加小黄条
        if (!+$('tr[selId="showSelCheckboxNum"]').length){
            $table.find('tr:first').after($newStr);
        }
        $ceilStr.find('.checkedNum').html(checkedNum);
        tableCeil.html($ceilStr);
        $('tr[selId="showSelCheckboxNum"] span.showSelCheckboxNumIn').html('已选中'+checkedNum+'条数据');
        if($selectAll.is(':checked')){ //再次判断全选是否选中
            selectAllState = 1;
        }

    }else{
        $table.find('tr[selId="showSelCheckboxNum"]').remove();
        tableCeil.empty();
    }
}
/*
 *New页面全选等处理
 * checkbox选择范围扩大到整个td,并显示选中条数
 * 注册方法：$('.a').setClick(setting);
 * setting 设置为 1 时显示选中条数;
 * input父级必须添加name，两级以上列表父级为 name="header"，单级父级列表为 name="content"
 * 全选input添加 iptId="selectAll"，单个input添加 iptId="selectSingle"
 * 吸顶数据显示在 .selectedData 标签中
 * */

/*
* table 表头吸顶效果
* (必加)在包裹着table的div上添加class名 ceilingType
* *需要保持thead和tbody的th与td都带有一致的min-width属性
* tbody必须存在数据 不然无法产生吸顶效果
* 如果表格用的是标准盒子模型 thead或tbody任意一个加了padding另一个需同样加上padding
* 如果表格用的是怪异盒子模型 tbody加了padding thead不需要加padding 同时加padding会导致吸顶时表头表格不对齐
* 当页面需要两个table切换做吸顶效果时，需要在一个吸顶时移除另一个table父级元素div的class
* * 注册方法：$('.ceilingType').ceilingType();*/
(function($,W){
    $.fn.setClick = function(o){
        var _this = $(this),
            checkBoxLen = '',
            setting = o && o.setting ? o.setting : false;
        var checkboxCheck = function(e,obj,objNode){
            e = e || event;
            e.stopPropagation();
            var iptId = $(obj).attr('iptId'),
                table = $(obj).closest('table'),
                selected = $(obj).is(':checked'),
                selectedAll = table.find('[iptId="selectAll"]').is(':checked'),
                $tableTh = table.children("thead").children('tr:first-child').children('th'),
                numtd = $tableTh.length,
                header =  $(obj).closest('tr[name = "header"]').length,
                tableCeil = $(obj).closest('body').find('.ceilingDiv').find('.selectedData'),
                newStr = '';

            //解决列表勾选显示的已选中多少条的小黄条跨列长度不对的问题，因为th可能有跨列属性，所以只取th节点数量是不对的
            $.each($tableTh, function (i, j) {
            	var colspan = $(j).attr('colspan');
				if(colspan && +colspan && +colspan !== 1){ //如果colspan有值，并且不等于0，并且不等于1
                    numtd += (+colspan - 1); //那么数量需要加等colspan-1
				}
            });

            //设置样式
            var setClass = function(obj1) {
            	var $that = $(obj1);
            	if(header){
					var $header = $that.closest('tr[name = "header"]');
					selected ? $header.addClass('selected').next('tr[name = "content"]').addClass('selected') : $header.removeClass('selected').next('tr[name = "content"]').removeClass('selected');
				}else {
					var $content = $that.closest('tr[name = "content"]');
					selected ? $content.addClass('selected') : $content.removeClass('selected');
				}
			};
            if (iptId === 'selectAll'){
                var checked = '';
                $(obj).closest('table').find('input[iptId="selectSingle"]').each(function(){
                    checked = $(this).is(":checked");
                    if(selected && !checked) $(this).prop('checked',true);
					if(!selected && checked) $(this).prop('checked',false);
                    setClass(this);
                });
            }else{
            	setClass(obj);
            }
            var inputNumtwo = $(table).find('input[iptId="selectSingle"]').length,
                checkedNum = $(table).find('input[iptId="selectSingle"]:checked').length;
            if(inputNumtwo == checkedNum && !selectedAll){
                table.find('[iptId="selectAll"]').prop('checked',true);
            }else if(inputNumtwo != checkedNum && selectedAll){
                table.find('[iptId="selectAll"]').prop('checked',false);
            }
            if(objNode){
                newStr = $('<tr class="showSelCheckboxNum articles-num-box" id="showSelCheckboxNum"><td ' +
					'class="articles-num-title articlesNumBox" colspan="'+numtd+'"><span class="articles-num-con articlesNumCon"></span><span class="articlesNumConAdd"></span></td></tr>');
                if(checkedNum > 0){
                    if (!+$('tr.showSelCheckboxNum').length){
                        table.find('tr:first').after(newStr);
                    }
                    tableCeil.html('&nbsp;&nbsp;已选中'+checkedNum+'条数据');
                    $('tr.showSelCheckboxNum .articlesNumCon').html('已选中<span class="f-black m-left5 m-right5 f-w600 checkedNum">'+checkedNum+'</span>条数据');
                    if(setting){
                        var transferObj = {
                            setting : setting
                        };
                        o && o.callBack && o.callBack(transferObj);
					}
                }else{
                    table.find('tr.showSelCheckboxNum').remove();
                    tableCeil.empty();
                }
                var $ceilingTypePlaceholderDiv = $('.ceilingTypePlaceholderDiv');
                if($ceilingTypePlaceholderDiv.length){
                    $ceilingTypePlaceholderDiv.css('height', table.children('thead').height() + 'px');
                }
            }
        };
        _this.on('click',function(){
            checkBoxLen = $(this).find('[type="checkbox"]').length;
            if(checkBoxLen == 1){
                $(this).find('[type="checkbox"]').click();
            }
        });
        _this.find('[type="checkbox"]').on('click',function (e) {
            e.stopPropagation();
            checkboxCheck(e,this,setting);
        });
    };
    $.fn.ceilingType = function () {
        var $ceilingType = $('.ceilingType'),
            $tr = $ceilingType.find('tbody:first').find('tr');

        if($tr.length >= 2 ){  //判断是否需要吸顶效果
            var $table = $ceilingType.children('table'),
				oldTableType = $table.hasClass('myj-table'),
				isBorder = $table.hasClass('in-table-border'),
				$thead = $ceilingType.find('thead:first'),
                $tbody = $ceilingType.find('tbody:first'),
				$td = $tbody.find('tr:first > td'),
                oTop = !oldTableType ? $thead.offset().top : $thead.offset().top + 50,
                $Caret = $thead.find('[name="Caret"]'),
                $tooltip = $thead.find('[data-toggle="tooltip"]'),
				$glyphicon = $thead.find('.glyphicon'),
				$iconfont = $thead.find('.iconfont'),
                $tableTd = $tbody.find('tr.content:first').children('td'),
				$ceilingTypePlaceholderDiv = '',
				theadTop = '',
				top = '';

            var setTableThWidth = function ($tableTdObj) {
                var rowspanNum = 0,
                    rowspanNumLast = 0,
                    colspanNum = 0,
                    colspanNumFirst = 0,
					isChildTable = false;
                $.each($tableTdObj, function (i, j) {
					isChildTable = $(j).hasClass('tdBorder');
                    //获取元素真实的内边距
                    var paddingLeft = (oldTableType || isChildTable) ? 0 : $(j).css('padding-left'),
                        paddingRight = (oldTableType || isChildTable) ? 0 : $(j).css('padding-right');

                    paddingLeft = paddingLeft ? paddingLeft.replace('px','') : 0;
                    paddingRight = paddingRight ? paddingRight.replace('px','') : 0;

                    var elseWidth = j.clientWidth - (Number(paddingLeft) + Number(paddingRight)) + (isChildTable ? -1 : ((isBorder) ? 2 : 0)), //tbody 下 tr 每个 td 的 width
                        gapNum = $tableTdObj.length  - $thead.children(':not(".showSelCheckboxNum")tr:last').children('th').length, //表头tr 与 tbody 的 td 差数
                        $th;

                    if(oldTableType) elseWidth += 1;
                    if($thead.children('tr:not(".showSelCheckboxNum")').length > 1 || i < gapNum){    //判断表头是否存在合并行的存在
                        if(colspanNum){
                            if($thead.children(':not(".showSelCheckboxNum")tr:first').children('th').eq(i - colspanNum).attr('rowspan')){
                                rowspanNumLast++;
                            }else if($thead.children(':not(".showSelCheckboxNum")tr:first').children('th').eq(i - colspanNum).attr('colspan')){
                                colspanNum += +$thead.children(':not(".showSelCheckboxNum")tr:first').children('th').eq(i - colspanNum).attr('colspan');
                            }
                            $th = $thead.children(':not(".showSelCheckboxNum")tr:last').children('th').eq(i - rowspanNum);
                            colspanNum--;
                        }else{
                            if($thead.children(':not(".showSelCheckboxNum")tr:first').children('th').eq(i - colspanNumFirst).attr('rowspan')){
                                $th = $thead.children(':not(".showSelCheckboxNum")tr:first').children('th').eq(i - colspanNumFirst);
                                rowspanNum++;
                            }else if(+$thead.children(':not(".showSelCheckboxNum")tr:first').children('th').eq(i - colspanNumFirst).attr('colspan') > 1){
                                colspanNum += +$thead.children(':not(".showSelCheckboxNum")tr:first').children('th').eq(i - colspanNumFirst).attr('colspan');
                                colspanNum--;
                                colspanNumFirst = colspanNumFirst ? rowspanNum : colspanNum;
                                $th = $thead.children(':not(".showSelCheckboxNum")tr:last').children('th').eq(i - rowspanNum);
                            }else{
                                $th = $thead.children(':not(".showSelCheckboxNum")tr:last').children('th').eq(i - rowspanNum);
                            }
                        }
                    }else{
                        $th = $thead.children(':not(".showSelCheckboxNum")tr:first').children('th').eq(i);
                    }
                    if($th.length){
                        $th.css({
                            'width': elseWidth + 'px',
                            'min-width': elseWidth + 'px',
                            'max-width': elseWidth + 'px'
                        });
                    }
                });
            };

            $thead.removeAttr('style');	//改成默认定位
            $ceilingType.addClass('relative').find('.ceilingTypePlaceholderDiv').remove();
            top = $table.offset().top - $ceilingType.offset().top;
            $table.addClass('borderTopNo');
            $thead.css({
                'position': 'absolute',
                'top': top + 'px',
                'left': 0,
				'border': '1px solid #e8e8e8',
				'border-bottom': 'none',
                'z-index': '99'
            });
			setTableThWidth($tableTd);
			$ceilingType.addClass('relative').prepend('<div class="ceilingTypePlaceholderDiv" ' +
				'style="position: relative; top: ' + top + 'px; width: 100%; height: ' + $thead.height() + 'px; z-index: -1;"></div>');

			$ceilingTypePlaceholderDiv = $ceilingType.find('.ceilingTypePlaceholderDiv');
            //封装公共方法:运动事件触发时，处理吸顶表头的宽高样式问题
            var setTableMoveThWidth = function () {
				$tableTd = $tbody.find('tr.content:first').children('td');
				if(W.pageYOffset >= oTop){	//大于等于table与顶端加上表头高度的距离时，固定定位
					var addWidth = document.body.scrollLeft,
						left = $ceilingType[0].getBoundingClientRect().left,
						$ceilingDiv = $('div#ceilingDiv:visible'),
						whetherCeil = $ceilingDiv.length ? $ceilingDiv.height() : 0,//获取ceilingDiv类吸顶
					    hasMoreTop;

					//判断是否有ceilingDiv类吸顶有，则取其高度
					if(whetherCeil){
						hasMoreTop = whetherCeil + 'px';
					}else{
						hasMoreTop = '0px';
					}

					$thead.css({
						'position': 'fixed',
						'top': hasMoreTop,
						'left': (oldTableType ? left + 1 : left) + 'px'
					});

					setTableThWidth($tableTd);

					if(addWidth) $thead.css('left', left + 'px');
					if($Caret.length){
						$Caret.addClass('hide').closest('span.paixuTit').addClass('p-right0');
					}
					if($tooltip.length){
						$tooltip.addClass('hide');
					}
					if($glyphicon.length){
						$glyphicon.addClass('hide').closest('.delimit-pop-up').addClass('hide');
					}
					if($iconfont.length){
						$iconfont.addClass('hide').closest('.delimit-pop-up').addClass('hide');
					}
				}else{
					$thead.css({
						'position': 'absolute',
						'top': top + 'px',
						'left': 0
					});
					$ceilingTypePlaceholderDiv.css('height', $thead.height());
					setTableThWidth($tableTd);
					if($Caret.length){
						$Caret.removeClass('hide').closest('span.paixuTit').removeClass('p-right0');
					}
					if($tooltip.length){
						$tooltip.removeClass('hide');
					}
					if($glyphicon.length){
						$glyphicon.removeClass('hide').closest('.delimit-pop-up').removeClass('hide');
					}
					if($iconfont.length){
						$iconfont.removeClass('hide').closest('.delimit-pop-up').removeClass('hide');
					}
					theadTop = $thead.offset().top; //获取一下表头到顶部的距离
					if ($thead.is(':visible') && (theadTop - oTop > 100 || theadTop - oTop < -100)) { //判断如果表头到顶部的位置减去原来的位置，如果差距浮动超过了正负100，则重新赋一下值
						oTop = !oldTableType ? $thead.offset().top : $thead.offset().top + 50;
					}
				}
			};

            W.onscroll = function(){  //鼠标滚动事件
                setTableMoveThWidth();
            };
            W.onresize = function(){ //浏览器缩放事件
            	setTableMoveThWidth();
            };

            //注册表头吸顶时主动调用一下该方法,有种情况是在吸顶的时候刷新pagelist导致表头没吸顶要滚动下才吸顶
			setTableMoveThWidth();
        }
    };
    try{ //下面这个方法可能会出现报错，加个捕获，防止程序报错之后无法正常执行别的代码
        window.requestAnimationFrame( $.fn.ceilingType);
	}catch (err){
	}
})(jQuery,window);


/*
 *页面全选处理(header与content皆有input时)
 * checkbox选择范围扩大到整个td,并显示选中条数
 * 注册方法：$('.a').selectAllFn(setting);
 * selecting 为设置的参数
 * 最外层添加class selectAllBox
 * tr父级必须添加name，两级以上列表父级为 name="header"，单级父级列表为 name="content"
 * 全选input添加 iptId="selectAll"，单个input添加 iptId="selectSingle"
 * */
(function($){
	$.fn.selectAllFn = function(o){
		var options = {
			displaySelNum: false //显示选中条数 false 不显示 true 显示
		};
		var _this = $(this),
			checkBoxLen = '',
			setting = o ? o : {};

		var newOptions = $.extend({}, options, setting);
		o && o.callBack && o.callBack(newOptions);
		var checkboxCheck = function(e, obj, options){
			e = e || event;
			e.stopPropagation();
			var iptId = $(obj).attr('iptId'),
				$box = $(obj).closest('.selectAllBox'),
				selected = $(obj).is(':checked'),
				selectedAll = $box.find('[iptId="selectAll"]').is(':checked'),
				$thead = $box.find('[iptId="selectAll"]').closest('table').children('thead'),
				numtd = $thead.children(':not(".showSelCheckboxNum")tr:first-child').children('th').length,
				header =  $(obj).closest('tr[name = "header"]').length,
				tableCeil = $(obj).closest('body').find('.ceilingDiv').find('.selectedData'),
				newStr = '';

			if(iptId === 'selectAll'){
				var checked = '';
				$box.find('input[iptId="selectSingle"]:not(":disabled")').prop('checked',selected);
				// $box.find('input[iptId="selectSingle"]').each(function(){
				// 	checked = $(this).is(":checked");
				// 	if(selected && !checked){
				// 		$(this).click();
				// 	}else if(!selected && checked){
				// 		$(this).click();
				// 	}
				// });
			}
            var name = $(obj).closest('tr').attr('name');
			if(name === 'content'){
			    var $table = $(obj).closest('table'),
                    selectSingleLen = $table.find('[name="content"]').length,
                    checkedLen = $table.find('[name="content"] [iptid="selectSingle"]:not(":disabled"):checked').length;
                if(selectSingleLen === checkedLen){
                    $table.find('[name="header"] [iptid="selectSingle"]').prop('checked', true);
                }else{
                    $table.find('[name="header"] [iptid="selectSingle"]').prop('checked', false);
                }
            }
			var inputNumtwo = $box.find('input[iptId="selectSingle"]:not(":disabled")').length,
				checkedNum = $box.find('input[iptId="selectSingle"]:not(":disabled"):checked').length;

			if(+inputNumtwo === +checkedNum){
				$box.find('[iptId="selectAll"]').prop('checked', true);
			}else if(+inputNumtwo !== +checkedNum && selectedAll){
				$box.find('[iptId="selectAll"]').prop('checked', false);
			}
			if(options.displaySelNum){
				newStr = $('<tr class="showSelCheckboxNum articles-num-box" id="showSelCheckboxNum">' +
					'<td class="articles-num-title articlesNumBox" colspan="'+numtd+'">' +
					'<span class="articles-num-con p-left20 articlesNumCon"></span><span class="articlesNumConAdd"></span></td></tr>');

				if(checkedNum > 0){
					if (!+$('tr.showSelCheckboxNum').length){
						$box.find('tr:first').after(newStr);
					}
					tableCeil.html('&nbsp;&nbsp;已选中'+checkedNum+'条数据');
					$('tr.showSelCheckboxNum .articlesNumCon').html('已选中<span class="f-black m-left5 m-right5 f-w600">'+checkedNum+'</span>条数据');
				}else{
					$box.find('tr.showSelCheckboxNum').remove();
					tableCeil.empty();
				}
                var $ceilingTypePlaceholderDiv = $('.ceilingTypePlaceholderDiv');
                if($ceilingTypePlaceholderDiv.length){
                    $ceilingTypePlaceholderDiv.css('height', $thead.height() + 'px');
                }
			}
			if(options.proCheckBox){
				if(name === 'header'){
					var uid = $(obj).closest('tr').attr('inwarehouseid'),
						types = $(obj).is(':checked'),
						checkAll = $(obj).closest('table').find('tr[uid="'+uid+'"]');
					$.each(checkAll,function(i,j){
						$(j).find('input').prop('checked',types);
					})
				}
			}
		};
		_this.off('click').on('click',function(){
			checkBoxLen = $(this).find('[type="checkbox"]').length;
			if(+checkBoxLen === 1){
				$(this).find('[type="checkbox"]').click();
			}
		});
		_this.find('[type="checkbox"]').off('click').on('click',function (e) {
			e.stopPropagation();
			checkboxCheck(e, this, setting);
		});
	}
})(jQuery);

/****************************2017.2.20 byzym 添加select选择框end*****************/
//订单留言 闭包 maijia_p=买家姓名 maijia_span=时间  maijia=买家留言   dianpu_p=店铺名 dianpu_span=时间 dianpu=店铺留言
(function ($) {
    var strOrder='<div class="word-box"><div class="whiteBar"></div><div class="wordbox scrollBar"></div><div class="triangle"></div></div>';
    var infoHtml = '<p class="&{class}">' +
        '<span class="&{class1}" style="margin-right:10px;">&{name}</span>' +
        '<span class="&{class2}">&{gmtCreateTime}</span>' +
        '</p><div class="&{class3}">&{content}</div> ';
    $(document).on('mouseover','.yan',function () {
        var yanModalObj=$(strOrder);
        var nameCent = JSON.parse($(this).attr('nameCent'));
        var plateform = nameCent.platform;//获取平台名称
        var msgList = nameCent.content;
        var newStr = '';
        if ($(this).find('.word-box').length < 1) {
            $.each(msgList,function(i){
                var oneList = msgList[i];
                var listType = oneList.type;
                if(listType == 0){
                    oneList.class = 'maijia_p';
                    oneList.class1 = 'maijia_name';
                    oneList.class2 = 'maijia_date';
                    oneList.class3 = 'maijia';
                }else{
                    oneList.class = 'dianpu_p';
                    oneList.class1 = 'dianpu_name';
                    oneList.class2 = 'dianpu_span';
                    oneList.class3 = 'dianpu';
                }
				oneList.content = removeScriptContent(oneList.content);
                newStr += infoHtml.format(oneList);
            });
            yanModalObj.find('.wordbox').append(newStr);
            $(this).append(yanModalObj);
            var divTop = $(this).find('.word-box').outerHeight() / 2;
            $(this).find('.word-box').css({'top': '-' + (divTop - 10) + 'px'});
            $(this).find('.triangle').css({'top': (divTop - 14) + 'px'});
        }
    })
})(jQuery);

// 显示或移除添加按钮
var showAdd = function (type) {
	if (type == 1) {
		if ($('tr[sourceUrlMarkTr="sourceUrlMarkTr"]').length == 5) {
			$('a[fstRow="fstAdd"]').css('display', 'none');
		}
	} else {
		$('a[fstRow="fstAdd"]').css('display', 'block');
	}
};

//数组唯一值
function uniqueArray(sourseArr){
	var res = [];
	var json = {};
	for(var i = 0; i < sourseArr.length; i++){
		if(!json[sourseArr[i]]){
			res.push(sourseArr[i]);
			json[sourseArr[i]] = 1;
		}
	}
	return res;
}
var expand_click = function(){
	//点击td选中checked  选中范围扩大 + 连动选择
	var objs = $('.input1');
	$('.expand_scope').click(function(){
		$(this).prop('checked')==true ? objs.prop('checked',true) : objs.prop('checked',false);
	});
	objs.click(function(e){
		objs.length == objs.filter(':checked').length ? $('.expand_scope').prop('checked',true) : $('.expand_scope').prop('checked',false);
		e.stopPropagation();
	});
	$('.expand_scope2').on('click',function(){
		if($(this).find('input').is(':checked')){
			$(this).find('input').prop('checked',false);
		}else{
			$(this).find('input').prop('checked',true);
		}
		objs.length == objs.filter(':checked').length ? $('.expand_scope').prop('checked',true) : $('.expand_scope').prop('checked',false)
	});
};
var expand_click2 = function(){
	//点击td选中checked  选中范围扩大
	$('.expand_scope').on('click',function(){
		if($(this).closest('.parent').find('.input1').is(':checked')){
			$(this).closest('.parent').find('.input1').prop('checked',false);
		}else{
			$(this).closest('.parent').find('.input1').prop('checked',true);
		}
		showSelCheckboxNum($(this).closest('.parent').find('.input1'));
	});
};
/*2017/11/3 byzym*/
var expand_click3 = function(){
    //点击td选中checked  选中范围扩大
    $('.expand_scope').on('click',function(){
        if($(this).closest('.parent').find('.input1').is(':checked')){
            $(this).closest('.parent').find('.input1').prop('checked',false);
        }else{
            $(this).closest('.parent').find('.input1').prop('checked',true);
        }
        showSelCheckboxNum($(this).closest('.parent').find('.input1'),'tableSingle');
    });
};
// base64加密开始
var keyBase64Str = "ABCDEFGHIJKLMNOP" + "QRSTUVWXYZabcdef" + "ghijklmnopqrstuv"
	+ "wxyz0123456789+/" + "=";

var encode64 = function(input) {
	var output = "";
	var chr1, chr2, chr3 = "";
	var enc1, enc2, enc3, enc4 = "";
	var i = 0;
	do {
		chr1 = input.charCodeAt(i++);
		chr2 = input.charCodeAt(i++);
		chr3 = input.charCodeAt(i++);
		enc1 = chr1 >> 2;
		enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
		enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
		enc4 = chr3 & 63;
		if (isNaN(chr2)) {
			enc3 = enc4 = 64;
		} else if (isNaN(chr3)) {
			enc4 = 64;
		}
		output = output + keyBase64Str.charAt(enc1) + keyBase64Str.charAt(enc2)
			+ keyBase64Str.charAt(enc3) + keyBase64Str.charAt(enc4);
		chr1 = chr2 = chr3 = "";
		enc1 = enc2 = enc3 = enc4 = "";
	} while (i < input.length);

	return output;
};
// base64加密结束

/**
 * 转化成北京时间
 * @param dateDime
 * @param timeZone
 * @returns {string}
 */
var parseToBeijingTime = function(dateTime,timeZone){
	if(dateTime=="" || dateTime==undefined || timeZone =="" || timeZone==undefined){
		return null;
	}else{
		var dateBefore = dateTime.slice(0,10);
		var timeBefore = dateTime.slice(11,20);
		var dateArray = dateBefore.split("-");
		var timeArray = timeBefore.split(":");
		var beijingTime = new Date();
		beijingTime.setTime(Date.UTC(dateArray[0],dateArray[1]-1/*月份从0开始*/,dateArray[2],timeArray[0],timeArray[1],timeArray[2],0) + timeZone*60*60*1000);
		var year=beijingTime.getUTCFullYear(),month,date,hour,minute;
		//年月日
		if (beijingTime.getUTCMonth()<9){
			var m=0;
			m=beijingTime.getUTCMonth()+1;
			month = "0" + m;
		}else{month = beijingTime.getUTCMonth()+1;}
		if (beijingTime.getUTCDate()<10){
			var d=0;
			d=beijingTime.getUTCDate();
			date = "0" + d;
		}else{date = beijingTime.getUTCDate();}
		var dateAfter = year + "-" + month + "-" + date;
		//时分
		if(beijingTime.getUTCHours()<10){hour = "0" + beijingTime.getUTCHours();}
		else{hour = beijingTime.getUTCHours();}
		if(beijingTime.getUTCMinutes()<10){minute = "0" + beijingTime.getUTCMinutes();}
		else{minute = beijingTime.getUTCMinutes();}

		var timeAfter = hour + ":" + minute +":" + timeArray[2];
		return dateAfter + " " + timeAfter;
	}
};
/*************转化成北京时间end***************/

/*
 *tab切换,没有内容切换不要加 defaultCheck*
 *联系以li上uid与.headTabPane上的id进行绑定*
 */
(function($,w,d){
    $(d).off('click', '.headTabBox.defaultCheck .headTabNav li');
    $(d).on('click', '.headTabBox.defaultCheck .headTabNav li', function(){
        var _this = this,
            tabId = $(_this).attr('uid');
        $(_this).closest('.headTabNav').find('li').removeClass('tab-check').addClass('borderBtmNo');
        $(_this).addClass('tab-check').removeClass('borderBtmNo');
        $(_this).closest('.headTabBox').find('.headTabPane').addClass('myj-hide');
        $(_this).closest('.headTabBox').find('#'+tabId).removeClass('myj-hide');
    })
})(jQuery, window, document);
//验证是否为阿里图片并转成https
var aliImgHandle = (function(){
	return {
		isaliToHttps: function(url){
            // 判断是否为阿里图片
            var alicdnCom = /alicdn.com/g.test(url);
            if(alicdnCom){
                var regExp = /g[0-9]{2}.a/g;
                url = url.replace(regExp,'ae01');
            }
			return url;
		}
	}
})();
/****图片base64前端直接传图片服务器****/
/*
* 还有问题，没全部走通
* FRONTENDIMGHANDLE.imgUpLoad(url,call,name,option) option未启用
*
*/
var FRONTENDIMGHANDLE = (function($){
    var regExp = 'wxalbum-10001658.image.myqcloud';
    return{
        urlToBlob: function(u,call){
            var _self = this;
            if(u.indexOf(regExp) == -1 && u.indexOf(';base64,') == -1){
                //var nu = u.replace('http:','').replace('https:','');
                var xhr = new XMLHttpRequest();
                xhr.responseType = 'blob';
                xhr.onload = function() {
                    this.status == 200 ? call({base:this.response,error:''}) : call({error:'error'}) ;
                };
                xhr.addEventListener('error',function(e){
                    call({error:'error'});
                },false);
                xhr.open('get', u, true);
                xhr.send();
                return true;
            }else if(u.indexOf(regExp) != -1){
                //('请选择非图片空间图片');
            }else if(u.indexOf(';base64,') != -1){
                _self.baseToBlob(u,call);
            }
        },
		downLoadReportIMG: function(imgPathURL) {
			var a =  '<a id="imgDownLoad" href="" download="imgLoad"></a>';
			if($('#imgDownLoad').length == 0){
				$('body').append($(a));
			}
			$('#imgDownLoad').attr('href',imgPathURL).click();
		},
        baseToBlob: function(b){
            if(b){
                var bytes = window.atob(b.split(',')[1]);
                var ab = new ArrayBuffer(bytes.length);
                var ia = new Uint8Array(ab);
                for(var i = 0; i < bytes.length; i++){
                    ia[i] = bytes.charCodeAt(i);
                }
                var blob = new Blob([ab],{type: b.split(',')[0].replace('data:','').replace(';base64','')});
                return blob;
            }
        },
        urlGetImgName: function(u){
            var imgName = u.split('/').pop();
            imgName = imgName.split('?')[0];
            return imgName;
        },
        imgUpLoad: function(url,call,name,option){
            if(!url) return;
            var _self = this;
            if(url.indexOf('base64') == -1){
                _self.urlToBlob(url,function(obj){
                    if(!obj.error){
                        _self.ajaxWX(obj.base, _self.urlGetImgName(u), call);
                    }
                })
            }else{
                if(name){
                    _self.ajaxWX(_self.baseToBlob(url), name, call);
                }else{
                    //('没有图片名');
                }
            }
        },
		// 图片接口改版（编辑器）
        ajaxWX: function (files, name, call, errorCall) {
            if(!files.length || !name) return;
            wxPicUpload.newImgUploadFromLocal(files, {type: 'album', isNeedTree: 0}, function(data, err){
                if(err === 1){
                    call(data);
                }else {// 上传图片失败后的回调
                    if(errorCall) errorCall(data);
				}
            });
        }
    };
})(jQuery);
/****图片base64前端直接传图片服务器end****/
//翻译用，过滤数组中空元素和非中文
var transateArrHandle = function(arr, sourceLanguage){
	if(arr && arr instanceof Array){
		var newArr = [];
		$.each(arr,function(i,j){
			j = $.trim(j);
			if(j && isContainLang(j, sourceLanguage)){
				newArr.push(j);
			}
		});
		return newArr;
	}else{
		return arr;
	}
};

//普通翻译用，控制切割数组长度
var transateObjHandle = function(arr,num, sourceLanguage) {
	var obj = {},
		n = 0,
		count;
	if(arr && arr instanceof Array){
		if(typeof(num) === 'string') { // 字符串类型的数字转换
			count = isNaN(num) ? 10:parseInt(num);
		}else if (+num && (+num%1 === 0) && typeof(+num) === 'number') { // 正整数类型直接使用
			count = num;
		} else {
			count = 10; // 默认请求的参数数组为10条数据
		}
		$.each(arr,function(i,j){
			j = $.trim(j);
			if(j && isContainLang(j, sourceLanguage)){
				if(obj[n] && obj[n].length === count) n++;
				if(!obj[n]) {
					obj[n] = [];
				}
				obj[n].push(j);
			}
		});
		return obj;
	}else{
		return arr;
	}
};

//翻译用，过滤数组中空元素和非目标语种
var transateArrLang = function(arr,language){
	if(arr && arr instanceof Array){
		var newArr = [];
		$.each(arr,function(i,j){
			j = $.trim(j);
			if(j && isContainLang(j,language)){
				newArr.push(j);
			}
		});
		return newArr;
	}else{
		return arr;
	}
};
//判断字符串中是否包含对应语种
var isContainLang = function (str, language) {
	if (language === 'zh' || !language) { //中文
		return /.*[\u4e00-\u9fa5]+.*/.test(str);
	} else if (language === 'en') { //英语
		return /.*[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u2C60-\u2C7F\uA720-\uA7FF\uAB30-\uAB6F\u1E00-\u1EFF\uFB00-\uFB06\uFF00-\uFF5E\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u0300-\u036F\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF]+.*/.test(str);
	} else if (language === 'ja') { //日语
		return /.*[\u0000-\u007F\u4E00-\u9FFF\u3400-\u4DBF\uF900-\uFAFF\u2F00-\u2FDF\u2E80-\u2EFF\u31C0-\u31EF\u2FF0-\u2FFF\u3000-\u303F\uFF00-\uFFEF\u3040-\u309F\u30A0-\u30FF\u31F0-\u31FF\uAC00-\uD7AF\uFE20-\uFE6F\u0080-\u00FF\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF\u2190-\u21FF]+.*/.test(str);
	} else if (language === 'es') { //西班牙语
		return /.*[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u2C60-\u2C7F\uA720-\uA7FF\uAB30-\uAB6F\u1E00-\u1EFF\uFB00-\uFB06\uFF00-\uFF5E\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u0300-\u036F\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF\u2190-\u21FF]+.*/.test(str);
	} else if (language === 'de') { //德语
		return /.*[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u2C60-\u2C7F\uA720-\uA7FF\uAB30-\uAB6F\u1E00-\u1EFF\uFB00-\uFB06\uFF00-\uFF5E\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u0300-\u036F\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF\u20AC\u2190-\u21FF]+.*/.test(str);
	} else if (language === 'fr') { //法语
		return /.*[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u2C60-\u2C7F\uA720-\uA7FF\uAB30-\uAB6F\u1E00-\u1EFF\uFB00-\uFB06\uFF00-\uFF5E\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u0300-\u036F\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF\u2190-\u21FF]+.*/.test(str);
	} else if (language === 'it') { //意大利语
		return /.*[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u2C60-\u2C7F\uA720-\uA7FF\uAB30-\uAB6F\u1E00-\u1EFF\uFB00-\uFB06\uFF00-\uFF5E\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u0300-\u036F\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF\u2190-\u21FF]+.*/.test(str);
	} else if (language === 'th') { //泰语
		return /.*[\u0000-\u007F\u0E00-\u0E7F\u0080-\u00FF\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF]+.*/.test(str);
	} else if (language === 'vi') { //越南语
		return /.*[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u2C60-\u2C7F\uA720-\uA7FF\uAB30-\uAB6F\u1E00-\u1EFF\uFB00-\uFB06\uFF00-\uFF5E\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u0300-\u036F\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF]+.*/.test(str);
	} else if (language === 'id') { //印尼语
		return /.*[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u2C60-\u2C7F\uA720-\uA7FF\uAB30-\uAB6F\u1E00-\u1EFF\uFB00-\uFB06\uFF00-\uFF5E\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u0300-\u036F\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF]+.*/.test(str);
	} else if (language === 'ft') { //台语
		return /.*[\u0000-\u007F\u4E00-\u9FFF\u3400-\u4DBF\uF900-\uFAFF\u2F00-\u2FDF\u2E80-\u2EFF\u31C0-\u31EF\u2FF0-\u2FFF\u3000-\u303F\uFF00-\uFFEF\u3040-\u309F\u30A0-\u30FF\u31F0-\u31FF\uAC00-\uD7AF\uFE20-\uFE6F\u0080-\u00FF\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF]+.*/.test(str);
	} else if (language === 'zh-tw') { //繁体
		return /.*[\u4e00-\u9fa5\u3400-\u4db5]+.*/.test(str);
	} else if (language === 'pt') { //葡萄牙语
		return /.*[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u2C60-\u2C7F\uA720-\uA7FF\uAB30-\uAB6F\u1E00-\u1EFF\uFB00-\uFB06\uFF00-\uFF5E\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u0300-\u036F\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF]+.*/.test(str);
	} else if (language === 'fil') { //菲律宾语
		return /.*[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u2C60-\u2C7F\uA720-\uA7FF\uAB30-\uAB6F\u1E00-\u1EFF\uFB00-\uFB06\uFF00-\uFF5E\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u0300-\u036F\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF]+.*/.test(str);
	} else if (language === 'pl') { //波兰语
        return /.*[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u2C60-\u2C7F\uA720-\uA7FF\uAB30-\uAB6F\u1E00-\u1EFF\uFB00-\uFB06\uFF00-\uFF5E\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u0300-\u036F\u2000-\u206F\u2200-\u22FF\u2100-\u214F\u2460-\u24FF\u2190-\u21FF]+.*/.test(str);
    } else if (language === 'auto' || language === 'ru' || language === 'he' || language === 'tr' || language === 'ko' || language === 'ar' || language === 'nl' || language === 'sv' || language === 'hi') { //自动识别+俄语+希伯来语+土耳其语+韩语+阿拉伯语+荷兰语+瑞典语+印地语
		return true;
	}
};

/*
 * 产品通用方法
 * */

/*打开选择网络图片弹层*/
var netImgModalShow = function(){
    $('#imgModal').modal('show');
};

/*根据平台码获取用于页面显示的平台名称*/
var platformDisplayMapping = function (platformCode, isGetEn) {
    var platformNameObj = {
			all: '全部',
			wish: 'Wish',
			smt: '速卖通',
			ebay: 'eBay',
			amazon: 'Amazon',
			lazada: 'Lazada',
			dh: '敦煌',
			cd: 'Cdiscount',
			shopify: 'Shopify',
			magento: 'Magento',
			magento2: 'Magento2',
			woocomm: 'Woocommerce',
			woocommerce: 'Woocommerce',
			jumia: 'Jumia',
			tiki: 'Tiki',
			shopee: 'Shopee',
			shopeeglobal: 'Shopee全球',
			joom: 'Joom',
			tophatter: 'Tophatter',
			walmart: 'Walmart',
			mymall: 'myMall',
			factorymkt: 'Factorymarket',
			ueeshop: 'Ueeshop',
			shopyy: 'Shopyy',
			vova: 'Vova',
			jd: '京东',
			jdid: '京东印尼',
			alibaba: 'Alibaba',
			shoplazza: '店匠',
			fanno: 'Fanno',
			fannoglobal: 'Fanno全球',
			tiktok: 'TikTok',
			tiktokglobal: 'TikTok全球',
			mercado: 'Mercado',
			pddkj: '拼多多跨境',
			poptemu: 'Temu半托管',
			gearbest: 'Gearbest',
			xshoppy: 'XShoppy',
			shopline: 'Shopline',
			bigcommer: 'BigCommerce',
			bigcommerce: 'BigCommerce',
			shopbase: 'ShopBase',
			allegro: 'Allegro',
			etsy: 'Etsy',
			kauflandde: 'Kaufland.de',
			coupang: 'Coupang',
			funpinpin: 'Funpinpin',
			allvalue: 'AllValue',
			ozon: 'Ozon',
			shopexp: 'ShopExpress',
			shopline2: 'Shopline2',
			fnac: 'Fnac',
			rakuten: 'Rakuten',
			rakutenjp: 'Rakuten JP',
			shoplus: 'Shoplus',
			qoo10: 'Qoo10',
			b2w: 'B2W',
			fruugo: 'Fruugo',
			daraz: 'Daraz',
			alicsp: 'CSP',
			aliarise: 'Miravia',
			choice: '速卖通全托管',
			alichoice: '速卖通全/半托管', // 首页店铺业绩图表展示
			shein: 'SHEIN',
			onbuy: 'OnBuy',
			global: '天猫淘宝海外',
			our: '其它',
			smtru: '速卖通俄罗斯',
			lzdchoice: 'Lazada全托管',
			voghion: 'Voghion'
		}, //新平台对接-平台名称展示文案，新增平台需要加上对应的展示名称文案，给用户看的
		platformName;

    if (isGetEn) { //如果是要取英文
    	$.each(platformNameObj, function (i, j) {
    	    //判断传进来的值是否等于对象中的中文名
    		if (platformCode === j) {
				platformName = i; //赋值英文
				return false; //结束循环
			}
    	});
	} else { //如果是取中文
		platformName = platformCode ? platformNameObj[platformCode.toLowerCase()] : '';
	}

    return platformName ? platformName : platformCode;
};
/*判断网络图片添加的url中是否存在base64编码格式的图片url*/
var judgeUrlIsBase64 = function (urlArr, isNotShowMsg) {
	var reg = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i;
    // var reg = /^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$/;
    if(typeof urlArr == "object"){
        for(var i in urlArr){
            urlArr[i] = $.trim(urlArr[i]);
            if (reg.test(urlArr[i])) {
                !isNotShowMsg && $.fn.message({type:"error",msg:"第"+(+i+1)+"条图片链接格式不支持添加！"});
                return false;
            }
        }
	}else{
        if (reg.test(urlArr)) {
			!isNotShowMsg && $.fn.message({type:"error",msg:"图片链接格式不支持添加！"});
            return false;
        }
	}
    return true;
};

/** 数字空默认设置为0 */
var setNumericDefault = function (source) {
	if (source){
		return source;
	}
	return 0;
};

/*
*
* window.open打开新窗体并用post方式传参
*
* */
function comOpenWinPost(url,args,options){
    var option = {
        'id':'comOpenWinPostForm',
        'method':'post',
        'action':url,
        'target':'_blank',
        'style':'display:none'
    };
    if(options && !isEmptyObject(options)){
        for(var key in options){
            option[key] = options[key];
        }
    }

    var _form = $("<form></form>",option).appendTo($("body"));

    for(var i in args){
        _form.append($("<input>",{'type':'hidden','name':i,'value':args[i]}));
    }

    _form.submit();
    _form.remove();
}
// 批量下载图片
function batchDownloadImgage (urls, fileName, uniqueKey) {
	if (!$.trim(urls)) {
        $.fn.message({type: 'error', msg: '图片地址为空'});
        return false;
	}

    var data = {
        urls : urls,
        fileName : fileName,
        uniqueKey : uniqueKey
    };
	commonProgressBarModalShow({
		title: '导出图片',
		ajaxUrl: gitWinLocHref() + 'album/batchDownloadFromProduct.json',
		ajaxData: data,
		hideDetail: true, //是否隐藏进度条弹层的详情结果信息
		isDownLoad: true, //是否是下载进度条弹层
		statusText: '正在导出中，请稍后...', //进度条执行过程中的提示文案
		successText: '导出文件已生成，文件将会在30分钟后失效,请立即下载<br/>' //进度条执行过程完成的提示文案
	});
}

/**批量导出**/
var batchExportData = function(url,param,title,pageSize){
	// 设置此次导出标题
	$(".batchExportDataTitle").text(title);

    $("#batchExportCosProductModal").modal("show");
    /*2017.2.10 byzym 二次刷新初始化*/
    $("#batchExportCosCheckReplicaProgressBarr").css("display", "none");
    setTimeout(function(){
        $("#batchExportCosCheckReplicaProgressBarr").css("width", 0+"%");
        $("#batchExportCosCheckReplicaProgressBarr").css("display", "");
    },10);
    $("#batchExportCosCheckReplicaProcessNumm").html("0");
    $("#exportCosReportShoww").empty();
    $('#exportCosUpDownloadboxZ').empty();
    $('ul[uid="dropdown-menuZ"]').empty();
    $('button[uid="dropdownZ"]').addClass('hide');
    $('div[uid="downloadFill"]').removeClass('btn-dropdown').find('button[uid="dropdown"]').removeClass('btn-determine').addClass('btn-gray').prop('disabled', true).css('color','#000000');
    var p = 0;		// 记录进度条的值
	$.ajax({
		type: "POST",
        url: url,
        data: param,
		dataType: "json",
        success: function(data){
        	if (+data.code && data.msg){
                $.fn.message({type:"error",msg:data.msg});
        		return;
			}
            var uuid = data.uuid ? data.uuid : data.data; //获取uuid
            if (typeof uuid === 'object' && uuid.uuid) {
                uuid = uuid.uuid;
            }
            checkProcessStatus(uuid, function(data){
                var num 	= data.num % 100;
                if(num<p && data.code!=1){
                    // 为了去掉变为n->0时的动画效果，在此先隐藏，然后再置0，最后再定时显示出来
                    $("#batchExportCosCheckReplicaProgressBarr").css("display", "none");
                    setTimeout(function(){
                        $("#batchExportCosCheckReplicaProgressBarr").css("display", "");
                    },1000);
                }
                p = num;
                if(data.code==0){
                    $("#batchExportCosCheckReplicaProgressBarr").css("width", num + "%");
                    $("#batchExportCosCheckReplicaProcessNumm").text(data.num);
                    $("#exportCosReportShoww").text(title + "正在导出中，请稍后下载...");
                    $("#exportCosReportShowww").text("");
                    $("#exportCosUpDownloadboxZu").text("");

                }else{
                    $("#batchExportCosCheckReplicaProgressBarr").css("width", "100%");
                    $("#batchExportCosCheckReplicaProgressBarr").removeClass("active");
                    $("#batchExportCosCheckReplicaProcessNumm").text(data.totalNum);
                    $("#exportCosReportShoww").empty();
                    $("#exportCosReportShowww").empty();
                    $('div[uid="downloadFill"]').addClass('btn-dropdown').find('button[uid="dropdownZ"]').removeClass('btn-gray').addClass('btn-determine').prop('disabled', false).css('color','#FFFFFF');
                    if (data.msg) {
                        var downUrl;

                        try {
							downUrl = JSON.parse(data.msg);
						} catch (e) {
							downUrl = {};
							downUrl.downUrlList = data.msg.split("|");
                            if (+data.code === -1 && !data.totalNum) {
                                $('#exportCosReportShoww').html('导出失败，' + downUrl.downUrlList);
                                return;
                            }
						}

                        var size = pageSize,spanStr= '',urls = downUrl.downUrlList,start = 1,
                            end;

                        if (urls.length > 1) {
                            $.each(urls, function (i,val) {
                                if (i == urls.length - 1) {
                                    end = "末尾";
                                } else {
                                    end = start - 1 + size;
                                }
                                spanStr += '<span class="inline-block" style="width: 33.33%;line-height: 30px;"><a role="menuitem" tabindex="-1" href="'+val+'">下载文件('+start+'-'+end+')</a></span>';
                                start += size;
                            });
                            $('#exportCosUpDownloadboxZ').html(spanStr);
                            $("#exportCosReportShoww").html('由于文件过大，已拆分为 '+urls.length+'个文件<br/>');
                        } else {
                            var downUrlAdder = urls[0];
                            if(downUrlAdder){
                                $("#exportCosReportShoww").html('导出文件已经生成: <span class="inline-block" style="width: 33.33%;line-height: 30px;"><a role="menuitem" tabindex="-1" href="'+downUrlAdder+'">立即下载文件</a></span>');
                            }
                        }
                    }
                }
            });
        },
        error:function(msg){
        }
    });
};

/**
 * 防止ajax加载的页面中含有的js请求自动加时间戳
 */
(function ($) {
    jQuery._evalUrl = function (url) {
        return jQuery.ajax({
            url: url,
            type: "GET",
            dataType: "script",
            async: false,
            global: false,
            "throws": true,
            cache: true
        });
    };
})(jQuery);

/*保留小数不四舍五入*/
function formatDecimal(num, decimal) {
	if(num !== ''){
        num = num.toString();
        var index = num.indexOf('.');
        if (index !== -1) {
            num = num.substring(0, decimal + index + 1)
        } else {
            num = num.substring(0)
        }
        return parseFloat(num).toFixed(decimal)
    }else{
        return '';
	}
}
/*保留小数不四舍五入*/

/*body点击其他地方时隐藏*/
var bodyClickHideDom = function (parentClass,childClass) {//parentClass = 点击展示的气泡之类的触发节点class；childClass = 展示之后的节点class
    var e = null,
        targ = null,
        tagBox = null;
    $(document).off('click','body').on('click','body',function (event) {
        e = event || window.event; //获取事件点击元素
        targ = e.target;
        tagBox = $(targ).closest(parentClass).length;

        $(childClass+'.block').removeClass('block');
        if(tagBox){
            $(targ).closest(parentClass).find(childClass).addClass('block');
        }
        e = null;
        targ = null;
        tagBox = null;
    });
};
/*body点击其他地方时隐藏end*/

/*根据产品链接获取产品来源平台*/
var getSourceName = function (sourceUrl) {
	var name = '';
	if(sourceUrl) {
		if (sourceUrl.indexOf("taobao.com") > 0) {
			name = "淘宝";
		} else if (sourceUrl.indexOf("tmall.com") > 0) {
			name = "天猫";
		} else if (sourceUrl.indexOf("1688.com") > 0) {
			name = "1688";
		} else if (sourceUrl.indexOf("aliexpress.com") > 0) {
			name = "速卖通";
		} else if (sourceUrl.indexOf("ebay.com/") > 0) {
			name = "ebay(美国)";
		} else if (sourceUrl.indexOf("ebay.com.au") > 0) {
			name = "ebay(澳大利亚)";
		} else if (sourceUrl.indexOf("ebay.at") > 0) {
			name = "ebay(奥地利)";
		} else if (sourceUrl.indexOf("ebay.ca") > 0) {
			name = "ebay(加拿大)";
		} else if (sourceUrl.indexOf("cafr.ebay.ca") > 0) {
			name = "ebay(加拿大 法语)";
		} else if (sourceUrl.indexOf("ebay.fr") > 0) {
			name = "ebay(法国)";
		} else if (sourceUrl.indexOf("ebay.de") > 0) {
			name = "ebay(德国)";
		} else if (sourceUrl.indexOf("ebay.in") > 0) {
			name = "ebay(印度)";
		} else if (sourceUrl.indexOf("ebay.ie") > 0) {
			name = "ebay(爱尔兰)";
		} else if (sourceUrl.indexOf("ebay.it") > 0) {
			name = "ebay(意大利)";
		} else if (sourceUrl.indexOf("ebay.com.my") > 0) {
			name = "ebay(马来西亚)";
		} else if (sourceUrl.indexOf("ebay.nl") > 0) {
			name = "ebay(荷兰)";
		} else if (sourceUrl.indexOf("ebay.ph") > 0) {
			name = "ebay(菲律宾)";
		} else if (sourceUrl.indexOf("ebay.pl") > 0) {
			name = "ebay(波兰)";
		} else if (sourceUrl.indexOf("ebay.com.sg") > 0) {
			name = "ebay(新加坡)";
		} else if (sourceUrl.indexOf("ebay.es") > 0) {
			name = "ebay(西班牙)";
		} else if (sourceUrl.indexOf("ebay.ch") > 0) {
			name = "ebay(瑞士)";
		} else if (sourceUrl.indexOf("ebay.vn") > 0) {
			name = "ebay(越南)";
		} else if (sourceUrl.indexOf("ebay.co.uk") > 0) {
			name = "ebay(英国)";
		} else if (sourceUrl.indexOf("ebay.com.hk") > 0) {
			name = "ebay(香港)";
		} else if (sourceUrl.indexOf("amazon.com/") > 0) {
			name = "亚马逊(美国)";
		} else if (sourceUrl.indexOf("amazon.ca") > 0) {
			name = "亚马逊(加拿大)";
		} else if (sourceUrl.indexOf("amazon.fr") > 0) {
			name = "亚马逊(法国)";
		} else if (sourceUrl.indexOf("amazon.de") > 0) {
			name = "亚马逊(德国)";
		} else if (sourceUrl.indexOf("amazon.it") > 0) {
			name = "亚马逊(意大利)";
		} else if (sourceUrl.indexOf("amazon.co.jp") > 0) {
			name = "亚马逊(日本)";
		} else if (sourceUrl.indexOf("amazon.com.mx") > 0) {
			name = "亚马逊(墨西哥)";
		} else if (sourceUrl.indexOf("amazon.co.uk") > 0) {
			name = "亚马逊(英国)";
		} else if (sourceUrl.indexOf("amazon.cn") > 0) {
			name = "亚马逊(中国)";
		} else if (sourceUrl.indexOf("amazon.in") > 0) {
			name = "亚马逊(印度)";
		} else if (sourceUrl.indexOf("amazon.es") > 0) {
			name = "亚马逊(西班牙)";
		} else if (sourceUrl.indexOf("amazon.sg") > 0) {
            name = "亚马逊(新加坡)";
        } else if (sourceUrl.indexOf("amazon.ae") > 0) {
            name = "亚马逊(阿联酋)";
        } else if (sourceUrl.indexOf("amazon.com.au") > 0) {
            name = "亚马逊(澳大利亚)";
        } else if (sourceUrl.indexOf("amazon.nl") > 0) {
            name = "亚马逊(荷兰)";
        } else if (sourceUrl.indexOf("amazon.com.tr") > 0) {
            name = "亚马逊(土耳其)";
        } else if (sourceUrl.indexOf("amazon.com.br") > 0) {
            name = "亚马逊(巴西)";
        } else if (sourceUrl.indexOf("jd.com") > 0) {
			name = "京东";
		} else if (sourceUrl.indexOf("alibaba.com") > 0) {
			name = "alibaba";
		} else if (sourceUrl.indexOf("dhgate.com") > 0) {
			name = "敦煌";
		} else if (sourceUrl.indexOf("etsy.com") > 0) {
			name = "etsy";
		} else if (sourceUrl.indexOf("lazada.co.id") > 0) {
			name = "lazada(印尼)";
		} else if (sourceUrl.indexOf("lazada.sg") > 0) {
			name = "lazada(新加坡)";
		} else if (sourceUrl.indexOf("lazada.com.my") > 0) {
			name = "lazada(马来)";
		} else if (sourceUrl.indexOf("lazada.vn") > 0) {
			name = "lazada(越南)";
		} else if (sourceUrl.indexOf("lazada.co.th") > 0) {
			name = "lazada(泰国)";
		} else if (sourceUrl.indexOf("lazada.com.ph") > 0) {
			name = "lazada(菲律宾)";
		} else if (sourceUrl.indexOf("pfhoo.com") > 0) {
			name = "PFHOO";
		} else if (sourceUrl.indexOf("wish.com") > 0) {
			name = "wish";
		} else if (sourceUrl.indexOf("chinabrands.com") > 0 || sourceUrl.indexOf("chinabrands.cn") > 0) {
			name = "chinabrands";
		} else if (sourceUrl.indexOf("www.banggood.com") > 0) {
			name = "banggood";
		} else if (sourceUrl.indexOf("us.banggood.com") > 0) {
			name = "usBanggood";
		} else if (sourceUrl.indexOf("haiyingshuju.com") > 0) {
			name = "海鹰";
		} else if (sourceUrl.indexOf("yixuanpin.cn") > 0) {
			name = "易选品";
		} else if (sourceUrl.indexOf("gearbest.com") > 0) {
			name = "gearbest";
		} else if (sourceUrl.indexOf("walmart.com") > 0) {
			name = "沃尔玛";
		} else if (sourceUrl.indexOf("joom.com") > 0) {
			name = "joom";
		} else if (sourceUrl.indexOf("tophatter.com") > 0) {
			name = "tophatter";
		} else if (sourceUrl.indexOf("shopee.tw") > 0) {
			name = "shopee(台湾)";
		} else if (sourceUrl.indexOf("shopee.sg") > 0) {
			name = "shopee(新加坡)";
		} else if (sourceUrl.indexOf("shopee.com.my") > 0) {
			name = "shopee(马来西亚)";
		} else if (sourceUrl.indexOf("shopee.com.mx") > 0) {
            name = "shopee(墨西哥)";
        } else if (sourceUrl.indexOf("shopee.co.th") > 0) {
			name = "shopee(泰国)";
		} else if (sourceUrl.indexOf("shopee.co.id") > 0) {
			name = "shopee(印尼)";
		} else if (sourceUrl.indexOf("shopee.ph") > 0) {
			name = "shopee(菲律宾)";
		} else if (sourceUrl.indexOf("shopee.vn") > 0) {
			name = "shopee(越南)";
		} else if (sourceUrl.indexOf("shopee.com.br") > 0) {
			name = "shopee(巴西)";
		} else if(sourceUrl.indexOf('yangkeduo.com') > 0 || sourceUrl.indexOf('pinduoduo.com') > 0) {
			name = "拼多多";
		} else if(sourceUrl.indexOf("distributor.taobao.global") > 0){
			name = "天猫淘宝海外";
		} else {
			name = "其它";
		}
	}

	return name;
};

//获取输入框光标位置，插入内容到光标位置
var getIptCursorInsertContent = function(iptId, textClass, call){//iptId=被插入的输入框节点id,textClass=要插入的内容节点class,这个class可以多个,
    var $iptId = document.getElementById(iptId), //获取输入框节点
        index = null;//光标所在输入框的位置下标,初始化为null

    $(document).off('click','.'+textClass).on('click','.'+textClass,function () {//给要插入的内容节点绑定点击事件
        var val = $iptId ? $iptId.value : '',//获取输入框现在的值
            value = '';
        if(index === null || index > val.length){//如果index = null或者大于当前输入框的值的长度,则默认把内容插入到输入框最后
            index = val.length; //获取当前输入框内容的长度
        }
        value = val.substring(0,index);
        val = val.substring(index) || '';

        value += $(this).attr('data-value') + val; //获取当前要插入的内容,这个内容需要用data-value来保存,因为不确定要插入的值到底是当前节点的html内容还是别的值
        $iptId ? $iptId.value = value : '';
        index += $(this).attr('data-value').length;//把光标下标位置改变成插入当前的内容之后的下标位置
		if (typeof call === 'function') {
			call($($iptId), value);
		}
    });

    $(document).off('click keyup','#'+iptId).on('click keyup','#'+iptId,function () { //给被插入内容的输入框节点绑定事件
        var cursurPosition=0;
        if(this.selectionStart){//非IE
            cursurPosition= this.selectionStart;
        }else{//IE
            try{
                var range = document.selection.createRange();
                range.moveStart('character',-this.value.length);
                cursurPosition = range.text.length;
            }catch(e){
                cursurPosition = 0;
            }
        }
        index = cursurPosition; //上面是去获取当前光标所在位置,如果还没有聚焦获取过光标,那么index = 0
    });
};

//字符串替换
/*
 *字符串内容替换，strings=原字符串，replaces=原字符串中要替换的字符，replaceResult=更换掉要替换的字符,istoLowerCase=是否要忽略大小写(true=是，false=否)；
 * 如：returnStringReplaceResult('abc','A','d',true) => 'dbc';
 *     returnStringReplaceResult('abc','A','d',false) => 'abc';
 *     istoLowerCase不传则默认false,istoLowerCase只能传boolean类型，如果是其他的也默认为false
 * 如果replaceResult参数不传，则默认把要替换的值去除，('abc','a','',false) => 'bc'
 * */
//此方法勿动，如若需要加新处理逻辑，先找相关人员确认
var returnStringReplaceResult = function (strings, replaces, replaceResult, istoLowerCase) {
    if(!strings || !replaces) return strings;
    var toLowerCaseCategoryNames = istoLowerCase === true ? strings.toLowerCase() : strings,//转小写之后的数据字段
        toLowerCaseVal = istoLowerCase === true ? replaces.toLowerCase() : replaces,//转小写之后的查询字段
        newStrArr = toLowerCaseCategoryNames.split(toLowerCaseVal), //根据查询字段把转了小写之后的数据字段进行分割
        joinStr = '',//用来拼接转了小写之后的数据字段，主要是为了截取原数据字段中的内容
        dataStr = '',//用来接收截取出来的原数据字段内容
        endStr = '',//用来接收拼接完之后的原数据字段
        length = newStrArr.length;
    for(var i = 0; i < length; i++){
        dataStr = strings.substring(joinStr.length, joinStr.length + newStrArr[i].length);//这里每次循环获取到的内容就是没有转小写的原数据字段
        joinStr += newStrArr[i]; //这里把当前循环数组下标中转了小写的内容拼接起来
        if(i === (length-1)){
            endStr += dataStr;
        }else{
            endStr += dataStr + (replaceResult !== null && replaceResult !== undefined ? replaceResult : ''); //把更换的内容拼接
        }
        joinStr += toLowerCaseVal; //把上面拼接的循环内容在加上要查询的内容,用来下次循环的时候截取下一段内容
    }
    return endStr;
};



//2019-11-21 hlx 增加搜索超过200提示
var inputInfoLengthJudgment = function (obj, num) {
	//替换空格，中文逗号，多余逗号  不回显
	var val =  $.trim($(obj).val()).replace(/，/g, ',').replace(/,+/g, ',').replace(/^,+/, '').replace(/,+$/gi, ''),
		skuCode = $.trim(val).split(','),
		platform = $('#platformFlag').val(),
		searchType = $('#productSearchType').val(),
		sType = $('#searchType').val() || $('#searchTypeShipping').val(),
		goodsType = $('#goodsSearchType').val(),//货品同步货品搜索类型
		move = $('#movePlatform').val(),
		type = 0,
		maxSearchNum = num ? num : 200;

	skuCode = $.grep(skuCode, function (x) { return $.trim(x).length > 0; });

	//模糊搜索大于30报错提示
	//searchType=下拉框值，0=模糊匹配；1=精确匹配；2=完全匹配
	//sType=搜索类型，各个平台对应搜索类型的值不一样，一般只有SKU、Parent SKU、产品ID等搜索类型有模糊、精确、完全的下拉框切换
	if (
		(platform === 'wish' && searchType === '0' && ((sType === '0' && $('#wishCrawl').val() !== 'wishCrawl') || sType === '1'))
		|| (platform === 'ebay' && searchType === '0' && (sType === '3' || sType === '4'))
		|| (platform === 'amazon' && searchType === '0' && (sType === '2' || sType === '3'))
		|| (platform === 'lazada' && searchType === '0' && sType === '1')
		|| (platform === 'shopify' && searchType === '1' && (sType === '2' || sType === '3'))
		|| (platform === 'shopee' && searchType === '0' && (sType === '1' || sType === '3'))
		|| (platform === 'joom' && searchType === '0' && (sType === '1' || sType === '0'))
		|| (platform === 'tophatter' && searchType === '0' && (sType === '1' || sType === '3'))
		|| (platform === 'WE' && searchType === '0' && (sType === '0' || sType === '1'))
		|| (platform === 'dh' && (sType === '1'))
		|| (platform === 'smt' && (sType === '1'))
		|| (platform === 'alibaba' && (sType === '1'))
		|| (platform === 'vova' && sType === '1')
		|| (platform === 'shopeeGlobal' && searchType === '0' && (sType === '1' || sType === '3'))
		|| (platform === 'shoplazza' && searchType === '0' && (sType === '1' || sType === '2'))
		|| ((platform === 'fanno' || platform === 'fannoGlobal') && searchType === '0' && sType === '1')
		|| ((platform === 'tiktok') && searchType === '0' && sType === '1')
	){
		if(type === 0 && skuCode.length > 30){
			type = 1;
			$.fn.message({type: 'error', msg: '模糊搜索最大搜索条数不能超过30，请使用精确搜索'})
		}
	}
	//searchType=下拉框值，0=模糊匹配；1=精确匹配；2=完全匹配
	//sType=搜索类型，各个平台对应搜索类型的值不一样，一般只有SKU、Parent SKU、产品ID等搜索类型有模糊、精确、完全的下拉框切换
	if (
		(move === 'wish' && searchType === '0' && (sType ==='0' || sType === '1'))
		|| (move === 'ebay' && searchType === '0' && (sType === '3' || sType === '4'))
		|| (move === 'amazon' && searchType === '0' && sType === '2')
		|| (move === 'lazada' && searchType === '0' && sType === '1')
		|| (move === 'shopify' && (sType === '2' || sType === '3'))
		|| ((move === 'shopee' || move === 'shopeeGlobal') && searchType === '0' && (sType === '1' || sType === '3'))
		|| (move === 'joom' && searchType === '0' && (sType === '1' || sType === '0'))
		|| (move === 'tophatter' && searchType === '0' && (sType === '1' || sType === '3' || sType === '4'))
		|| (move === 'dh' && (sType === '1'))
		|| (move === 'smt' && (sType === '1'))
		|| (move === 'alibaba' && (sType === '1'))
		|| (move === 'vova' && sType === '1')
		|| (move === 'shoplazza' && searchType === '0' && (sType === '1' || sType === '2'))
		|| ((move === 'fanno' || move === 'fannoGlobal') && searchType === '0' && sType === '1')
		|| ((move === 'tiktok') && searchType === '0' && sType === '1')
	){
		if(type === 0 && skuCode.length > 30){
			type = 1;
			$.fn.message({type: 'error', msg: '模糊搜索最大搜索条数不能超过30，请使用精确搜索'})
		}
	}
	if (
		(platform === 'wish'  && (sType === '0' || sType === '1' || sType === '3'))
		|| (platform === 'ebay'  && (sType === '3' || sType === '4' || sType === '2'))
		|| (platform === 'amazon'  && (sType === '2' || sType === '3'))
		|| (platform === 'lazada'  && (sType === '1' || sType === '3'))
		|| (platform === 'shopify'  && (sType === '2' || sType === '3' || sType === '4'))
		|| (platform === 'shopee' && (sType === '4' || sType === '1' || sType === '5'))
		|| (platform === 'joom'  && (sType === '1' || sType === '0' || sType === '3'))
		|| (platform === 'tophatter'  && (sType === '1' || sType === '3' || sType === '4'))
		|| (platform === 'WE'  && (sType === '1' || sType === '3' || sType === '0'))
		|| (platform === 'dh' && (sType === '1' || sType === '2'))
		|| (platform === 'smt' && (sType === '1' || sType === '2'))
		|| (platform === 'alibaba' && (sType === '1' || sType === '2'))
		|| (platform === 'vova' && (sType === '2' || sType === '3'))
		|| (platform === 'shopeeGlobal' && (sType === '1' || sType === '3' || sType === '4'))
		|| (platform === 'shoplazza' && sType !== '0')
		|| ((platform === 'fanno' || platform === 'fannoGlobal') && sType !== '2')
		|| ((platform === 'tiktok') && sType !== '2')
		|| (platform === 'walmart'  && (sType === '1' || sType === '3' || sType === '4'))
        || (platform === 'shein'  && (sType === '1' || sType === '2' || sType === '3'))
		|| (platform === 'aliChoice' && ((sType === '1' || sType === '3') || (goodsType === '2' || goodsType === '3' || goodsType === '4')))
		|| (platform === 'aliPopChoice' && goodsType === '2' || goodsType === '3' || goodsType === '4')
		|| (platform === 'aliCsp'  && (sType === '1' || sType === '3'))
		|| (['pddkj', 'popTemu'].includes(platform)  && (sType === '2' || sType === '3'))
		|| (platform === 'tiktokGlobal'  && (sType === '1' || sType === '3'))
		|| (platform === 'coupang'  && (sType === '2' || sType === '3'))
		|| (platform === 'daraz'  && (sType === '1' || sType === '3'))
		|| (platform === 'mercado'  && (sType === '2' || sType === '3'))
		|| (platform === 'ozon'  && (sType === '2' || sType === '3'))
		|| (platform === 'smtru'  && (sType === '1' || sType === '3')) // sku 产品id
		|| (platform === 'lzdChoice' && (sType === '1' || sType === '2'))
	){
		if(type === 0 && skuCode.length > maxSearchNum){
			type = 1;
			$.fn.message({type: 'error', msg: '最大搜索条数不能超过' + maxSearchNum})
		}
	}
	if (
		(move === 'wish'  && (sType === '0' || sType === '1' || sType === '3'))
		|| (move === 'ebay'  && (sType === '3' || sType === '4' || sType === '2'))
		|| (move === 'amazon'  && (sType === '2' || sType === '3'))
		|| (move === 'lazada'  && (sType === '1' || sType === '3' || sType === '2'))
		|| (move === 'shopify'  && (sType === '2' || sType === '3' || sType === '4'))
		|| ((move === 'shopee' || move === 'shopeeGlobal') && (sType === '1' || sType === '4'))
		|| (move === 'joom'  && (sType === '1' || sType === '0' || sType === '3'))
		|| (move === 'tophatter'  && (sType === '1' || sType === '3' || sType === '4'))
		|| (move === 'dh' && (sType === '1' || sType === '2'))
		|| (move === 'smt' && (sType === '1' || sType === '2'))
		|| (move === 'alibaba' && (sType === '1' || sType === '2'))
		|| (move === 'vova' && (sType === '2' || sType === '3'))
		|| (move === 'shoplazza' && sType !== '0')
		|| ((move === 'fanno' || move === 'fannoGlobal') && sType !== '2')
		|| ((move === 'tiktok') && sType !== '2')
	){
		if(type === 0 && skuCode.length > maxSearchNum){
			type = 1;
			$.fn.message({type: 'error', msg: '最大搜索条数不能超过' + maxSearchNum})
		}
	}

	return type;
};

//浏览器数据库注册
var MYJ_DB_DATABASE = ''; //注册成功之后这个变量则会有增删改查的操作方法
var openIndexedDBDataBase = function (options, isOtherDB) {
	//如果一个页面需要多个浏览器数据库，则isOtherDB传true，会把数据库对象返回，调用方法那里用个变量接收
	if(isOtherDB){
		return MYJ_INDEXEDDB_DATABASE(options); //注册方法；options=注册配置参数
	}else{ //如果不需要多个，则可以直接使用MYJ_DB_DATABASE全局变量
		MYJ_DB_DATABASE = MYJ_INDEXEDDB_DATABASE(options); //注册方法；options=注册配置参数
	}
    //以下是注册浏览器数据库需要的配置参数，别删
    // MYJ_DB_DATABASE = MYJ_INDEXEDDB_DATABASE({
    //     objectStoreNames:'t_order_scanshipments_' + $('#userId').val(), //数据库表名,必填,字符串类型，下划线分割，不可包含空格和特殊字符,用t_加模块\功能名_加用户id，加用户id主要是为了防止用户a和用户b在同一台电脑操作时数据存储出错
    //     uniqueIndex: {package_id:'id'}, //唯一索引，必填，键值对对象方式创建，只能有一个，key名下划线分割
    //     otherIndex: {}, //其他索引,选填，键值对对象方式创建,可创建多个，key名下划线分割
    //     init: function(data){ //初始化回调方法,选填,function类型,参数data则是当前数据库表存在的所有数据,可在此方法中做初始化渲染等操作
    //         if(data){
    //         	if(!+data.code && data.result && data.result.length){
    //         	}
    //         }
    //     },
    //     error: function(data){ //错误回调方法
    //     }
    // });
};
var SMT_MOTOR_ATTR_ID = 231208804; //汽配属性id，用来判断选择的产品分类是否有汽配属性，如果有则可以设置汽配兼容表信息

var SMT_MOTORBIKE_ATTRVALUE_ID = 200004548; // 摩配属性值id，用来判断选择的产品分类有汽配属性时是否是摩托车配件
//语音播放
var SPEAK_HANDLE = (function(){
    var speakReadyTimeout = null, //判断可能正常播放延时
        speakEndType = false, //判断播放完毕
        speech = window.speechSynthesis;

    //获取系统版本
    var getTypeOfWin7 = function(){
        var userAgent = navigator.userAgent.toLowerCase(),
            typeOfWin7 = false;

        if (userAgent.indexOf('win') > -1 && (userAgent.indexOf('windows nt 6.1') > -1 || userAgent.indexOf('windows 7') > -1)) {
            typeOfWin7 = true;
        }
        return typeOfWin7;
    };

	//判断当前是否是谷歌浏览器，并且浏览器版本是88版以上
	var getTypeOfChrome = function(){
		var userAgent = navigator.userAgent.toLowerCase();
		if(userAgent && userAgent.indexOf('chrome') !== -1){
			var versionNum = userAgent.split('chrome/')[1];
			versionNum = versionNum.split('.')[0];
			if(+versionNum > 88){
				return true;
			}
		}
		return false;
	};

    //历史记录判断
    var getVoiceAbnormalType = function(){
        var voicePlayback = myjStorage.objGet('voicePlayback')(),
            voiceType = voicePlayback ? voicePlayback.type : '',
            abnormalType = true;

		if(getTypeOfChrome()){ //如果是谷歌浏览器
			abnormalType = false;
		}else{
			if(!voiceType){
				abnormalType = false;
			}else{
				//有历史--判断时间超长
				var voiceTimeNow = new Date();
				var voiceTime = voicePlayback ? voicePlayback.time : 0;

				voiceTimeNow = voiceTimeNow.getTime();
				if(voiceTime && voiceTimeNow){
					var timeDiff = voiceTimeNow - voiceTime;
					if(voiceType === 'yesPlay'){ //正常30天检测一次
						if(+timeDiff > 2592000000){
							abnormalType = false
						}
					}else{ //异常7天检测一次
						if(+timeDiff > 604800000){
							abnormalType = false
						}
					}
				}
			}
		}

        return {
            voiceType: voiceType ? voiceType : 'notPlay',
            abnormalType: abnormalType
        };
    };

    //正常语音播放
    var textSpeakNormal = function(text, realLen, type){
        //获取当前时间
        var mydate = new Date();

        mydate = mydate.getTime(); //获取当前时间毫秒数

        //初始化
        clearTimeout(speakReadyTimeout);

        //语音播放
        var msg = new SpeechSynthesisUtterance(),
            startType = null;

        msg.rate = 1.5;
        msg.lang = 'zh-CN'; //设置播放语言
        msg.text = text; //获取并设置说话时的文本
        speech.cancel(); //删除队列中所有的语音.如果正在播放,则直接停止
        speech.speak(msg); //将对应的实例添加到语音队列中

        if(type === 'abnormal'){
        	var playOtherVideo = function () {
				speakEndType = false;
				//停止当前播放
				speech.cancel();

				//设置历史
				myjStorage.objSet('voicePlayback', {
					type: 'notPlay',
					time: mydate
				})();

				//其他语音播放
				textSpeakOther(text, realLen, 'skip');
        	};
			msg.onerror = function(){
				if (startType === null || startType === 'start' || startType === 'no') {
					clearTimeout(speakReadyTimeout);
					playOtherVideo();
				}
			};

			msg.onstart = function(){
				speakEndType = true;
                startType = 'start';

                //设置历史
                myjStorage.objSet('voicePlayback', {
                    type: 'yesPlay',
                    time: mydate
                })();
            };
            speakReadyTimeout = setTimeout(function(){
                if(startType !== 'start'){
					playOtherVideo();
				} else {
					startType = 'no';
				}
            }, 500)
        }

        msg.onend = function(){
            speakEndType = false;
            msg = null;
        };
    };

    //其他语音播放
    var textSpeakOther = function(text, realLen, type){
        //进入拦截
        if(!type || (type === 'skip' && !speakEndType)){
            var voice, url;
			speakEndType = true;
            // url = 'https://tts.baidu.com/text2audio?spd=7&lan=zh&ie=UTF-8&text=' + encodeURIComponent(text);
            // url = 'https://tsn.baidu.com/text2audio?spd=7&lan=zh&ie=UTF-8&text=' + encodeURIComponent(text);
            // url = 'https://fanyi.baidu.com/gettts?spd=7&source=web&lan=zh&text=' + encodeURIComponent(text);
            //有道翻译内容需要用空格隔开不能用|隔开
			if (text.indexOf('|') !== -1) {
				text = text.replace(/\|/g, ' ');
			}
			//有道翻译-get翻译，get翻译数字字母 需要用空格隔开不能用|隔开
			url = 'https://dict.youdao.com/dictvoice?le=zh-CHS&audio=' + encodeURIComponent(text);
			// url = 'https://tts.youdao.com/fanyivoice?le=zh-CHS&word=' + encodeURIComponent(text);
            // url = 'https://fanyi.sogou.com/reventondc/synthesis?lang=zh-CHS&from=translateweb&speaker=3&text=' + encodeURIComponent(text);
			voice = document.createElement('audio');
			voice.id = 'dictVoice';
			voice.src = url;
            voice.playbackRate = 1.2; //播放倍速1.2
			voice.play();
			speakEndType = false;

			//有道翻译-post翻译，返回一个mp3文件地址，post翻译数字字母 可以用空格隔开也可以用|隔开，用post翻译则把上面的代码注释
			/*$.ajax({
				type: 'POST',
				url: 'https://aidemo.youdao.com/ttsapi',
				data: {
					text: text, //播放内容
					speed: '1', //播放语速
					lan: 'zh-CHS', //播放语言
					voice: 3 //3=男声，6=女声
				},
				dataType: 'json',
				success: function(data){
					if(+data.errorCode === 0){
						voice = document.createElement('audio');
						voice.id = 'dictVoice';
						voice.src = data.data;
						// voice.playbackRate = 1.2; //播放倍速1.2
						voice.play();
						speakEndType = false;
					}
				}
			});*/
        }
    };

    return {
        read: function(text){
            if(text && typeof(text)=='string'){
                //真实长度
                var realLen = text.length;

                //语音文字处理
                if(text.replace(/[0-9a-zA-Z]/ig, '') === ''){
                    text = text.split('');
                    text = text.join('|');
                }

				//判断历史
				var voiceData = getVoiceAbnormalType();

				//历史数据判断
				if(!voiceData.abnormalType){
					//尝试语音
					textSpeakNormal(text, realLen, 'abnormal');
				}else{
					//有历史
					if(voiceData.voiceType === 'yesPlay'){
						//执行语音
						textSpeakNormal(text);
					}else{
						//执行其他语音
						textSpeakOther(text, realLen, 'skip');
					}
				}
            }
        }
    }
})();

/*
 * 上传文件类型限制
 * @param fileArr 需要判断类型的file数组
 * @param type 可上传的文件类型
 * @return index 当前file数组中是否存在不可上传的类型的文件，如果返回的值是-1代表不存在，如果返回不是-1代表存在，返回的值是file数组对应的下标
 */
var filesTypeRestrict = function (fileArr, type, platform) {
	var index = -1; //设置默认值
	if(fileArr && fileArr.length && type){ //验证file数组是否有值，验证类型是否有值
        $.each(fileArr, function (i, j) { //循环file数组
        	var name = j.name; //获取当前文件名称
        	name = name.split('.'); //根据点号分割
        	if(name.length >= 2){ //判断分割的数组是否大于等于2
				name = name[name.length -1] ? name[name.length -1] : ''; //获取数组最后一个下标的值，这个值就是文件名称的后缀格式
				if(name){ //判断后缀格式是否有值
					name = (platform && platform === 'smt') ? name : name.toLowerCase(); //把需要验证的文件类型转小写(速卖通平台视频格式要验证大写)
                    type = type.toLowerCase(); //把验证类型转小写
					if(type.indexOf(name) === -1){ //如果当前文件的后缀格式不存在验证类型中，则当前文件不支持上传
						index = i; //把当前数组下标返回
						return false;
					}
				}
			}
		});
	}
	return index;
};

/*
* 把rgb颜色转为16进制颜色
* @returns 16进制的字符串颜色，例如：'rgb(0,0,0)'.colorRGBTransColorHex(); return结果：#000000;
* */
String.prototype.colorRGBTransColorHex = function(){
    var that = this;
    if(/^(rgb|RGB)/.test(that)){
        var aColor = that.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(','),
            strHex = '#';

        for(var i = 0; i < aColor.length; i++){
            var hex = Number(aColor[i]).toString(16);
            if(+hex < 10){
                hex = '0' + hex;
            }
            strHex += hex;
        }
        if(strHex.length !== 7){
            strHex = that;
        }
        return strHex;
    }else{
        return that;
    }
};

//防止别人iframe嵌套我们网站，如果两个地址不相等则跳回我们的地址
var judgeDxmHrefIsIframe = function () {
	if(window.top.location !== window.location){
		window.location = gitWinLocHref() + '404.htm';
	}
};

var stringToObject = function (data) {
	if (typeof data == 'string'){
		return JSON.parse(data);
	}
	return data;
};

//时间戳转日期格式，判断值是否是数字，如果是数字则转日期格式，不是数字则不转
var timestampTranDate = function (data, timeType) {
    var date = '';
	switch (typeof data) {
		case 'string':
			if(!isNaN(data)){
				date = new Date(+data).format(timeType ? timeType : 'yyyy-MM-dd');
				//如果转出来的日期为1970，或者data小于5000，则当前传进来的data是年份
				if (date.indexOf('1970') !== -1 || +data < 5000) {
					//data不转数字直接获取日期格式数据
					date = new Date(data).format(timeType ? timeType : 'yyyy');
				}
				data = date;
			}
			break;
		case 'number':
			data = new Date(data).format(timeType ? timeType : 'yyyy-MM-dd');
			break;
		case 'object':
			if (Array.isArray(data)) {
				for (var i = 0; i < data.length; i++) {
					if (!isNaN(data[i])) {
                        date = new Date(+data[i]).format(timeType ? timeType : 'yyyy-MM-dd');
                        //如果转出来的日期为1970，或者data小于5000，则当前传进来的data是年份
                        if (date.indexOf('1970') !== -1 || +data[i] < 5000) {
                            //data不转数字直接获取日期格式数据
                            date = new Date(data[i]).format(timeType ? timeType : 'yyyy');
                        }
                        data[i] = date;
					}
				}
			}
			break;
	}
	return data;
};

/*
* 浏览器大小发生改变时监听事件
* @param selectedName resize事件自定义名称，用来清除和重新绑定指定名称事件，防止清除到其它的事件，必传参数
* @param call 回调函数，处理监听到浏览器大小改变后需要执行的程序，必传参数
* */
var initWindowResizeFn = function (selectedName, call) {
	$(window).off('resize.' + selectedName).on('resize.' + selectedName, function () {
		typeof call === 'function' && call();
	});
};

/*
 * 公用悬停显示文案可移入
 * @param selector 需要添加悬停气泡的节点
 * @param position  气泡显示的位置，right,bottom,left,不传默认top
 * @param isText  显示的内容是否为纯文本，true则用text生成
 * @param width  气泡的长度 类型：Number (不能超过540)
 */
var publicHoverTextCanBeMovedIn = function (selector, position, isText, width) {
	position = position || '';
	var commonBrandMsgStr='<div class="common-word-box commonWordBox ' + position + '"><div class="whiteBar"></div><div class="common-word-in wordbox scroll-bar"></div><div class="common-triangle"></div></div>',
		hoverStoFn = '';

	var mouseoverFn = function(obj){
		var $that = $(obj),
			$commonBrandMsgStr = $(commonBrandMsgStr),
			content = $that.attr('data-content'),
			$commonWordBox = $that.find('.commonWordBox');

		$('.commonWordBox').removeClass('show'); //把所有气泡移除掉show
		if (!content) return; //如果没有内容则不生成悬停气泡
		if ($commonWordBox.length < 1) {
			$that.addClass('common-hover-prompt');

			if (isText) {
				$that.append($commonBrandMsgStr);
				$commonBrandMsgStr.find('.wordbox').text(content);
			} else {
				content = removeScriptContent(content);
				$commonBrandMsgStr.find('.wordbox').append(content);
				$that.append($commonBrandMsgStr);
			}
			$commonWordBox = $that.find('.commonWordBox');
		}
		$commonWordBox.addClass('show'); //给当前悬停的气泡加一个show

		var divTop = $commonWordBox.outerHeight(),
			divLeft = $commonWordBox.outerWidth(),
			boxTop = +($that.offset().top - window.scrollY).toFixed(1),
			boxLeft = +($that.offset().left- window.scrollX).toFixed(1);

		if (position === 'right') {
			boxTop = boxTop - 5 + 'px !important;';
			boxLeft = boxLeft + $that.outerWidth() + 10 + 'px !important;';
		} else if (position === 'left') {
			boxTop = boxTop - 5 + 'px !important;';
			boxLeft = boxLeft - divLeft - 10 + 'px !important;';
		} else if (position === 'bottom') {
			boxTop = boxTop + $that.outerHeight() + 10 + 'px !important;';//divTop
			boxLeft = (boxLeft - (divLeft / 2) + ($that.outerWidth() / 2) + 8).toFixed(1) + 'px';
		} else {
			boxTop = boxTop - divTop - 10 + 'px';//divTop
			boxLeft = (boxLeft - (divLeft / 2) + ($that.outerWidth() / 2) + 8).toFixed(1) + 'px';
		}

		var widthNum = width ? width : divLeft; // 自定义气泡宽度
		$commonWordBox.attr('style', 'top: ' + boxTop + '; left: ' + boxLeft + '; width: ' + widthNum + 'px;')
			.find('.wordbox').css('width', (widthNum + 2) + 'px');
		$that.find('.common-triangle').css({'left': ((widthNum / 2) - 15).toFixed(1) + 'px'});

		clearTimeout(hoverStoFn); //清除延时器

		if ($that.closest('.modal.in').length) {
			$that.closest('.modal-body').off('scroll.commonWordBoxHover').on('scroll.commonWordBoxHover', function () {
				$that.find('.commonWordBox').removeClass('show');
				$that.closest('.modal-body').off('scroll.commonWordBoxHover');
			});
		} else {
			$(document).off('scroll.commonWordBoxHover').on('scroll.commonWordBoxHover', function () {
				$that.find('.commonWordBox').removeClass('show');
				$(document).off('scroll.commonWordBoxHover');
			});
		}
	};

	var mouseoutFn = function(obj){
		var $that = $(obj);
		clearTimeout(hoverStoFn);
		hoverStoFn = setTimeout(function () { //离开气泡时，0.5秒之后在把show去掉
			$that.find('.commonWordBox').removeClass('show');
			if ($that.closest('.modal.in').length) {
				$that.closest('.modal-body').off('scroll.commonWordBoxHover');
			} else {
				$(document).off('scroll.commonWordBoxHover');
			}
		}, 500);
	};

	if(typeof selector === 'string'){
		$(selector).find('.commonWordBox').remove();
		$(document).off('mouseover', selector).on('mouseover', selector, function () {
			mouseoverFn(this);
		});
		//离开延迟隐藏，离开之后0.5秒在隐藏气泡，防止用户无法悬停到气泡上操作
		$(document).off('mouseout', selector).on('mouseout', selector, function () {
			mouseoutFn(this);
		});
	}else{
		$(selector).find('.commonWordBox').remove();
		$(selector).off('mouseover').on('mouseover', function () {
			mouseoverFn(this);
		});
		//离开延迟隐藏，离开之后0.5秒在隐藏气泡，防止用户无法悬停到气泡上操作
		$(selector).off('mouseout').on('mouseout', function () {
			mouseoutFn(this);
		});
	}

};
/*
 * 公用点击显示文案
 * @param selector 需要添加点击气泡的节点
 * @param position  气泡显示的位置，right,bottom,left,不传默认top
 * @param call  点击气泡生成时走的气泡初始化方法
 */
var publicClickTextCanBeMovedIn = function (selector, position, isText, call) {
	position = position || '';
	var commonBrandMsgStr='<div class="common-word-box ' + position + '"><div class="whiteBar"></div><div class="common-word-in wordbox scroll-bar"></div><div class="common-triangle"></div></div>',
		hoverStoFn = '';

	var mouseoverFn = function(obj){
		var $that = $(obj),
			$commonBrandMsgStr = $(commonBrandMsgStr),
			content = $that.attr('data-content'),
			$commonWordBox = $that.find('.common-word-box');

		if ($commonWordBox.length < 1) {
			$that.addClass('common-click-prompt');
			if (isText) {
				$that.append($commonBrandMsgStr);
				$commonBrandMsgStr.find('.wordbox').text(content);
			} else {
				content = removeScriptContent(content);
				$commonBrandMsgStr.find('.wordbox').append(content);
				$that.append($commonBrandMsgStr);
			}
			$commonWordBox = $that.find('.common-word-box');
			var divTop = $commonWordBox.outerHeight(),
				divLeft = $commonWordBox.outerWidth();
			$commonWordBox.css({'top': '-' + (divTop + 5) + 'px', 'left': -(divLeft / 2 - $that.outerWidth() / 2 + 10) + 'px'});
			$that.find('.common-triangle').css({'top': (divTop - 4) + 'px', 'left': (divLeft / 2) + 'px'});
		}
		$('.common-word-box').removeClass('show'); //把所有气泡移除掉show
		$commonWordBox.addClass('show'); //给当前悬停的气泡加一个show
		// clearTimeout(hoverStoFn); //清除延时器
	};

	var mouseoutFn = function(obj){
		var $that = $(obj);
		// hoverStoFn = setTimeout(function () { //离开气泡时，0.5秒之后在把show去掉
			$that.find('.common-word-box').removeClass('show');
		// }, 500);
	};

	if(typeof selector === 'string'){
		// 点击后弹出气泡
		$(document).off('click.clickShowPublic', selector).on('click.clickShowPublic', selector, function (e) {
			mouseoverFn(this);
			call && typeof call === 'function' && call(this);
		});
	}else{
		// 点击后弹出气泡
		$(selector).off('click.clickShowPublic').on('click.clickShowPublic', function () {
			mouseoverFn(this);
		});
	}
	$(document).off('click', '.common-word-box').on('click', '.common-word-box', function (e) {
		var event = e || W.event;
		event.stopPropagation();
	});
	//点击其他位置隐藏气泡
	$(document).off('click.clickHidePublic').on('click.clickHidePublic', function (e) {
		var event = e || window.event,
			$event = $(event.target);
		if($event.closest('.variantClickDiv').length) return;
		if(!$event.closest('.common-word-box').length) mouseoutFn(this);
	});
};


//图片url转file文件
var imageUrlTransFiles = function (imgUrl, call, flag) {
    if (flag) return;//结束程序
	var that = this,
		image = new Image();

	if(imgUrl.indexOf('?') !== -1){
        imgUrl = imgUrl + '&v=' + Math.random();
    }else{
        imgUrl = imgUrl + '?v=' + Math.random();
    }
	image.src = imgUrl;
	image.setAttribute('crossOrigin', 'anonymous'); //跨域
	image.onload = function () {
		var dataURL = getBase64Image(image); //获取base64的图片地址

        if(dataURL.isBase64){
            try {
                var myFile = '',
                    arr = dataURL.url.split(','), //把图片地址分割
                    mime = arr[0].match(/:(.*?);/)[1],
                    bstr = atob(arr[1]), //转blob类型
                    n = bstr.length,
                    u8arr = new Uint8Array(n);

                //处理数据，准备生成file文件流
                for (var i = 0; i < n; ++i) {
                    u8arr[i] = bstr.charCodeAt(i);
                }
                myFile = new Blob([u8arr], {type: mime}); //把处理好的base64的图片地址转成Blob文件流,new File不支持ie，所以需要用Blob

                typeof call === 'function' && call(myFile, imgUrl);
            }catch(e){
                typeof call === 'function' && call();
            }
        }else{
            typeof call === 'function' && call();
        }
	};

	image.onerror = function(){
		typeof call === 'function' && call();
	};
};
//获取base64流图片地址，把img节点丢进canvas后转成base64图片流地址
var getBase64Image = function(img) {
	var canvas = document.createElement('canvas'),
        imgURLObj = {
	        url: img.src,
            isBase64: false
        };

    try {
        canvas.width = img.width;
        canvas.height = img.height;
        var ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0, img.width, img.height);
        var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
        imgURLObj.url = canvas.toDataURL('image/' + ext);
        imgURLObj.isBase64 = true;
    }catch(e){}
	return imgURLObj;
};


// 变种sku二维数组重组
/*
* getSkuDataRecombination({
*   arr: skuObj,//必填
*   attrArr: ['oldName', 'newName', 'skuId'],//必填，数组类型，拼接时用到的属性
*
*   len: skuObj.length,//选填，arr长度
*   idx:0,//初始化传入的arr数组的下标，选填，如果是从0开始，可不传
*   splitStr: '$&$',//普通分隔符，选填，不传默认使用$&$分割
*   node:'',//选填，如果是空字符串可不传
*   nodeSplitStr: '$%$',//与node拼接的分隔符，选填，不传默认使用$%$
*   newArr: ['name', 'value', 'isLine', 'attrSypeName'],//选填，数组类型，需要返回新数组才传
*   call: skuValueBuild//选填，需要在方法里执行时可传函数方法名
* });
* */
var getSkuDataRecombination = function (options) {
	var arr = options.arr,
		attrArr = options.attrArr,
		newArr = options.newArr ? options.newArr : null;

	//判断必填项是否为空
	if((!arr || !arr.length) && (!attrArr || !attrArr.length)) {
		if (newArr) return newArr;
		return;
	}

	var idx = options.idx ? options.idx : 0,
		node = options.node ? options.node : null,
		len = options.len ? options.len : arr.length,
		splitStr = options.splitStr ? options.splitStr : '$&$',
		nodeSplitStr = options.nodeSplitStr ? options.nodeSplitStr : '$%$',
		call = options.call ? options.call : null;

	//根据属性内容拼接字符串
	var getObjStr = function (obj) {
		var objStr = '';

		$.each(attrArr, function (a, b) {
			objStr += (objStr ?  splitStr : '') + obj[b];
		});

		return objStr;
	};

	arr[idx] && $.each(arr[idx], function(i, j){
		var obj = getObjStr(j),
			nodeStr = node ? (node + nodeSplitStr + obj) : obj;

		if (idx + 1 === len) {//结束递归
			if (newArr) newArr.push(nodeStr);
			call && typeof call === 'function' && call(nodeStr);//执行外部传进来的函数方法
		} else {
			//递归二维数组
			var newArrData = getSkuDataRecombination(
				{
					arr: arr,
					idx: idx + 1,
					node: nodeStr,
					len: len,
					newArr: newArr,
					splitStr: splitStr,
					attrArr: attrArr,
					nodeSplitStr: nodeSplitStr,
					call: call
				});
			if (newArr) newArr = newArrData;
		}
	});

	if (newArr) return newArr;//返回重组数据
};

// 产品标签去除中文特殊符号方法
var tagNameClearZhSymbol = function (obj, removeStr) {
	var val = $(obj).val();
	if (removeStr) { //判断是否有其它指定的符号要去除，有则去除
		removeStr = removeStr.split('%-%'); //可能有多个要去除的符号，用%-%分隔
		for (var i = 0; i < removeStr.length; i++) {
			val = val.replaceAll(removeStr[i], '');
		}
	}
	return val.replace(/[\uFE30-\uFF0b]|[\uff0d-\uFFA0]|[\u3002|\uff1f|\uff01|\u3001|\uff1b|\uff1a|\u201c|\u201d|\u2018|\u2019|\uff08|\uff09|\u300a|\u300b|\u3008|\u3009|\u3010|\u3011|\u300e|\u300f|\u300c|\u300d|\ufe43|\ufe44|\u3014|\u3015|\u2026|\u2014|\uff5e|\ufe4f|\uffe5]/g, '');
};

// 字符串过滤中文和中文符号方法
var strClearZhSymbol = function (valStr, removeStr) {
	if (valStr) {
		// 判断是否有其它指定的符号要去除，有则去除
		if (removeStr) {
			// 可能有多个要去除的符号，用%-%分隔
			removeStr = removeStr.split('%-%');
			for (var i = 0; i < removeStr.length; i++) {
				valStr = valStr.replaceAll(removeStr[i], '');
			}
		}
		valStr = valStr.replace(/[\u2E80-\u2EFF\u2F00-\u2FDF\u3000-\u303F\u31C0-\u31EF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FBF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF]+/g, '');
	}
	return valStr;
};

/*
 * 根据时区转换当前的时间
 * @param timeZoneOffset 北京时间与所选时区之间的时差，以小时为单位
 * @param format 转换后的时间格式
 */
var getDateByTimeZone = function (timeZoneOffset, format) {
	var timestamp = Date.now();
	return new Date(timestamp - timeZoneOffset * 60 * 60 * 1000).format(format || 'yyyy-MM-dd hh:mm:ss');
};

// 将后台返回给前台的错误提示中的特定标签转化为a标签
var strFilterUrl = function(str){
	var strs = '';
	strs = str.replace(/%#W7Ox0Ze%#/g,'<a href=\"');
	strs = strs.replace(/%#uIGOykJW%#/g,'" target="_blank" >');
	strs = strs.replace(/%#ulvupSta%#/g,'</a>');
	return strs;
};

/**
* 全局公用进度条弹层方法
* @param option 配置对象
* @param option.title 进度条弹层的头部标题，不传默认“提示”
* @param option.hideDetail 进度条弹层的详情结果信息是否隐藏，如果是true则隐藏进度条结果详情结果信息
* @param option.statusText 进度过程中提示进度文案
* @param option.successText 进度结束提示文案
* @param option.unit 导出数量单位，默认'张'
* @param option.isDownLoad 是否是下载进度条弹层
* @param option.hasTarget 下载链接是当前页打开，还是新开页打开，false是当前页打开，否则是新开页打开
* @param option.rebuild   多链接下载是否显示’xxx进行中‘提示文案
* @param option.hasDownBtn  多链接下载对于单个是否显示下载按钮
* @param option.progressCall  兼容进度条计算公式不一样
* @param option.singleExportText 单个excel下载完成文案
* @param option.downloadText 批量excel下载文件完成文案
* @param option.isMultiDownloadLink 是否是多个下载链接
* @param option.multiFileSize 每个文件的数据条数
* @param option.noticeText 给底部添加说明文案dom节点
* @param option.ajaxUrl 必传：进度条弹层的ajax请求地址
* @param option.ajaxData 进度条弹层的ajax请求参数
* @param option.callback 进度条弹层执行完的回调函数，callback(result, $commonProgressBarModal)返回最终的结果数据和进度条弹层的dom对象
* @param option.closeCallback 进度条弹层关闭时的回调函数，closeCallback(result) 返回这次轮询获取到的结果数据，因为用户可能在进度条还没执行完毕就点击关闭了
* @param option.promptStripTop 进度条弹层顶部的黄色提示条节点内容，如果传了值则默认显示黄色提示条，如果不传则不显示
* @param option.uuid 用来轮询查询进度状态的，如果有传则不调用ajaxUrl接口去获取uuid
* */
var commonProgressBarModalShow = function (option) {
	var $commonProgressBarModal = $('#commonProgressBarModal'),
		$commonProgressBarBox = $('#commonProgressBarBox'),
		$commonProgressBarStatus = $('#commonProgressBarStatus'),
		$commonCosUpDownloadBox = $('#commonCosUpDownloadBox'),
		$commonCosReportShow = $('#commonCosReportShow'),
		$commonCosGroupBox = $('#commonCosGroupBox'),
		$commonCosGroupShow = $('#commonCosGroupShow'),
		$commonProgressBarDetail = $('#commonProgressBarDetail'),
		$downloadFill = $commonProgressBarModal.find('.downloadFill'),
		$commonExportShowBox = $commonProgressBarModal.find('.commonExportShowBox'),
		$commonNotExportShowBox = $commonProgressBarModal.find('.commonNotExportShowBox'),
		$commonExportStatusMsg = $commonProgressBarModal.find('#commonExportStatusMsg'),
		$commonExportNum = $commonProgressBarModal.find('#commonExportNum'),
		$commonExportUnit = $commonProgressBarModal.find('#commonExportUnit'),
		$commonPromptStripTop = $commonProgressBarModal.find('.commonPromptStripTop'),
		$commonNoticeFooter = $commonProgressBarModal.find('#commonNoticeFooterId'), //提示说明
		progressResultData = '';

	//是否是下载进度条弹层
	if (option.isDownLoad) {
		$commonProgressBarStatus.removeClass('f-red');
		$commonNotExportShowBox.addClass('hide');
		$commonExportShowBox.removeClass('hide');
		$commonExportStatusMsg.text('导出中');
		$commonExportNum.text('0');
		$downloadFill.addClass('no-show-menu').removeClass('hide')
			.find('button[uid="dropdown"]').prop('disabled', true);
	} else {
		$commonProgressBarStatus.addClass('f-red');
		$downloadFill.addClass('hide');
		$commonNotExportShowBox.removeClass('hide');
		$commonExportShowBox.addClass('hide');
	}

	if (option.promptStripTop) {
		$commonPromptStripTop.show().find('.commonPromptStripCon').html(option.promptStripTop);
	} else {
        $commonPromptStripTop.hide().find('.commonPromptStripCon').empty();
    }

	$commonProgressBarStatus.text(option.statusText || '进行中...'); //状态文案初始化为进行中
	$commonProgressBarDetail.empty(); //详情内容清空

	$commonCosUpDownloadBox.empty(); // 多个下载文件按钮清空
	$commonCosReportShow.empty(); // 拆分文件个数文案清空
	$commonCosGroupBox.empty();
	$commonCosGroupShow.empty();
	$commonNoticeFooter.empty(); //清空提示文案
	$commonProgressBarStatus.removeClass('hide'); // 显示提示

	// 如果返回多个下载链接
	if (option.isMultiDownloadLink) {
		$commonProgressBarStatus[option.rebuild ? 'removeClass' : 'addClass']('hide'); // 隐藏底部下载按钮提示
		$downloadFill.addClass('hide'); // 隐藏弹窗底部下载按钮
	}

	$commonExportUnit.text(option.unit || ' 张'); // 导出的数量单位设置，默认'张'
	$('.commonProgressBarModalTitle').text(option.title || '提示'); //进度条弹层标题
	$commonProgressBarBox.css({'display': 'none', 'width': '0%'}); //把进度条隐藏后归零
	var sto = setTimeout(function () {
		clearTimeout(sto);
		sto = null;
		$commonProgressBarBox.css('display', ''); //10毫秒后把进度条显示，防止用户看到进度条倒退回百分之0的状态
	}, 10);

	//有提示说明
	if (option.noticeText) {
		$commonNoticeFooter.html(option.noticeText);
	}

	$commonProgressBarModal.modal('show'); //显示进度条弹层

	//uuid轮询方法
	var checkProcessStatusFn = function (uuid) {
		var num = 0,
			status = option.statusText || '进行中...',
			isFinish = false;
		//调用checkProcessStatus方法，传uuid和一个回调函数
		checkProcessStatus(uuid, function(data){
			progressResultData = data;

			if (option && typeof option.progressCall === 'function') { //兼容进度条计算公式不一样
				num = option.progressCall(data);
			} else {
				num = Math.round(data.totalNum ? (data.num / data.totalNum * 100) : (data.num % 100));//这里num是在计算进度条的进度
			}

			//是否是下载进度条弹层
			if (option.isDownLoad) {
				if(!+data.code){
					//设置num值，更改进度条的进度走向
					$commonProgressBarBox.css('width', num + '%');
					$commonExportNum.text(data.num);
				}else if(+data.code === -1){
					//设置num值，更改进度条的进度走向
					$commonProgressBarBox.css('width', num + '%');
					$commonExportNum.text(data.num);
					status = data.msg;
					$commonProgressBarStatus.addClass('f-red').removeClass('hide'); // 隐藏底部下载按钮提示
				}else{
					$commonProgressBarBox.css('width', '100%').removeClass('active'); //把进度条设为百分之100
					$commonExportStatusMsg.text('已导出');
					$commonExportNum.text(data.num);
					status = option.successText || '';
					if(data.msg){
						status = option.successText || '导出文件已生成，文件将会在5分钟后失效,请立即下载<br/>';
						$downloadFill.removeClass('no-show-menu').find('button[uid="dropdown"]').prop('disabled', false);
					}
					// 是否返回多个下载链接
					if (option.isMultiDownloadLink) {
						var downUrl = {},
							size = option.multiFileSize,
							spanStr = '',
							urls = [],
							start = 1,
							end;
						try {
							downUrl = JSON.parse(data.msg);
						} catch (e) {
							if (data.msg.indexOf('|') === -1 && data.msg.indexOf(';') !== -1) {
								downUrl.downUrlList = data.msg.split(';');
							} else {
								downUrl.downUrlList = data.msg.split('|');
							}
							if (!data.totalNum && downUrl.downUrlList.indexOf('该模板没有可导出的数据') !== -1) {
								$('#commonProgressBarStatus').html('导出失败，' + downUrl.downUrlList);
								return;
							}
						}
						urls = downUrl.downUrlList;

						if (urls.length > 1) {
							$.each(urls, function (i,val) {
								if (i === urls.length - 1) {
									end = '末尾';
								} else {
									end = start - 1 + size;
								}
								spanStr += '<span class="inline-block w33-percentum" style="line-height: 30px;"><a role="menuitem" tabindex="-1" href="'+val+'">下载文件('+start+'-'+end+')</a></span>';
								start += size;
							});
							$commonCosUpDownloadBox.html(spanStr);
							$commonCosReportShow.html('由于文件过大，已拆分为 ' + urls.length + '个文件<br/>');
						} else {
							//对于单个是否显示下载按钮
							if (option.hasDownBtn && data.msg) {
								$commonProgressBarModal.find('.highSpeedDownload').find('a').attr({
									'href': data.msg,
									'target': option.hasTarget === false ? '_self' : '_blank'
								});
								$commonProgressBarModal.find('.standbyDownload').find('a').attr({
									'href': getDownloadUrl(data.msg),
									'target': option.hasTarget === false ? '_self' : '_blank'
								});
								//显示下载按钮
								$downloadFill.removeClass('no-show-menu hide').find('button[uid="dropdown"]').prop('disabled', false);
							} else {
								var downUrlAdder = urls[0],
									singleExportText = option.singleExportText || '导出文件已经生成',
									downloadText = option.downloadText || '立即下载文件';
								if (downUrlAdder) {
									$commonCosReportShow.html(singleExportText + ': <span class="inline-block w33-percentum" style="line-height: 30px;"><a role="menuitem" tabindex="-1" href="' + downUrlAdder + '">' + downloadText + '</a></span>');
								}
								//隐藏导出进行提示
								$commonProgressBarStatus.addClass('hide');
							}
						}

					} else {
						$commonProgressBarModal.find('.highSpeedDownload').find('a').attr({
							'href': data.msg,
							'target': option.hasTarget === false ? '_self' :'_blank'
						});
						$commonProgressBarModal.find('.standbyDownload').find('a').attr({
							'href': getDownloadUrl(data.msg),
							'target':  option.hasTarget === false ? '_self' :'_blank'
						});
					}
					isFinish = true;
				}
			} else {
				if(!+data.code){ //这里是确认是否执行完毕，任务还在执行时进入
					//设置num值，更改进度条的进度走向
					$commonProgressBarBox.css('width', num + '%');
				}else{ //如果任务完成了则走这里
					status = '已完成!';
					$commonProgressBarBox.css('width', '100%').removeClass('active'); //把进度条设为百分之100
					isFinish = true;
				}
			}
			$commonProgressBarStatus.html(status); //状态
			if (!option.hideDetail) { //如果hideDetail为true则不显示详情信息，false则赋值显示
				var msg = data.msg ? strFilterUrl(data.msg) : '';
				$commonProgressBarDetail.html(msg); //详情
			}
			if (isFinish && option && typeof option.callback === 'function') {
				option.callback(progressResultData, $commonProgressBarModal);
			}
		});
	};
	//如果从外面传了uuid进来，则不需要再调用接口，直接走uuid轮询方法获取进度状态
	if (typeof option.uuid !== 'undefined') {
		checkProcessStatusFn(option.uuid);
	} else { //如果没有uuid，则走接口获取uuid
		var ajaxOption = {
			url: option.ajaxUrl,
			data: option.ajaxData || {},
			loading: false,
			success: function (datas) {
				if(!+datas.code){ //判断code为0
					var uuid = datas.uuid ? datas.uuid : datas.data; //获取uuid

					if(datas && datas.data && datas.data.uuid) uuid = datas.data.uuid;

					checkProcessStatusFn(uuid);
				} else {
					$commonProgressBarBox.css('width', '100%').removeClass('active'); //把进度条设为百分之100
					$commonProgressBarStatus.html('已完成!'); //状态
					if (!option.hideDetail) { //如果hideDetail为true则不显示详情信息，false则赋值显示
						var msg = datas.msg ? strFilterUrl(datas.msg) : '';
						$commonProgressBarDetail.html(msg); //详情
					}
					if (option && typeof option.callback === 'function') {
						option.callback(progressResultData, $commonProgressBarModal);
					}
				}
			}
		};
		if (typeof option.cache !== 'undefined') {
			ajaxOption.cache = option.cache;
		}
		if (typeof option.processData !== 'undefined') {
			ajaxOption.processData = option.processData;
		}
		if (typeof option.contentType !== 'undefined') {
			ajaxOption.contentType = option.contentType;
		}
		if (typeof option.pointKey !== 'undefined') {
			ajaxOption.pointKey = option.pointKey;
		}
		//调用请求，获取uuid
		MYJ.ajax(ajaxOption);
	}

	$commonProgressBarModal.off('hidden.bs.modal').on('hidden.bs.modal', function (e) {
		//关闭弹层时结束定时获取执行进度请求的定时器
		if(intervalProcessStatus){
			clearInterval(intervalProcessStatus); //清除定时请求后台状态的定时器
			intervalProcessStatus = null;
		}
		if (option && typeof option.closeCallback === 'function') {
			option.closeCallback(progressResultData);
		}
	});
};

//获取国家站点简码对应的中文名称
var getSiteZhName = function (code) {
	if (code) {
		code = code.toLowerCase();
		switch (code) {
			case 'us':
				code = '美国';
				break;
			case 'gb':
			case 'uk': //GB和UK都是英国二字码
				code = '英国';
				break;
			case 'de':
				code = '德国';
				break;
			case 'fr':
				code = '法国';
				break;
			case 'ru':
				code = '俄罗斯';
				break;
			case 'jp':
				code = '日本';
				break;
			case 'es':
				code = '西班牙';
				break;
			case 'it':
				code = '意大利';
				break;
			case 'au':
				code = '澳大利亚';
				break;
			case 'my':
				code = '马来西亚';
				break;
			case 'vn':
				code = '越南';
				break;
			case 'id':
				code = '印度尼西亚';
				break;
			case 'sg':
				code = '新加坡';
				break;
			case 'ph':
				code = '菲律宾';
				break;
			case 'th':
				code = '泰国';
				break;
			case 'br':
				code = '巴西';
				break;
			case 'mx':
				code = '墨西哥';
				break;
			case 'co':
				code = '哥伦比亚';
				break;
			case 'cl':
				code = '智利';
				break;
			case 'pl':
				code = '波兰';
				break;
			case 'tw':
			case 'zhtw':
			case 'zh-tw':
			case 'zh_tw':
			case 'cntw':
			case 'cn-tw':
			case 'cn_tw':
				code = '台湾';
				break;
		}
	}
	return code;
};

/*
* 前端js转zip压缩
* data = 要压缩的数据，必须是字符串，数组和对象需要转json
* fileName = 自定义压缩的文件名称
* call = 压缩完成后的回调方法，会返回一个content数据，content则是压缩后的数据文件
* 注：call回调函数返回的content数据是文件类型，需要使用new FormData()存起来后传给后端
* 示例：
* webJsDataToZip(JSON.stringify(data), 'xxx.txt', function (content) {
        var formData = new FormData();

        formData.append('file', content); //定义数据对象key为file的value值是content
        formData.append('xxx', 'xxx'); // 有其它需要传给后端的参数则多个formData.append即可

        $.ajax({
            type: 'POST',
            url: 'xxx/xxx.json', //请求地址
            data: formData, //请求参数
            cache: false,//上传文件无需缓存，必须
            processData: false,//用于对data参数进行序列化处理 这里必须false
            contentType: false, //必须
            success: function(data) {

            }
        });
    });
* */
var webJsDataToZip = function (data, fileName, call) {
	var newZip = new JSZip();

	newZip.file(fileName, data);
	newZip.generateAsync({
		type: 'blob',// 压缩类型
		compression: 'DEFLATE', // STORE=默认不压缩 DEFLATE=需要压缩
		compressionOptions: {
			level: 9 // 压缩等级1~9 1压缩速度最快，9最优压缩方式
		}
	}).then(function(content) {
		call(content);
	});
};

/*
* 前端特殊字符转义
* @param str：'abc&nbsp;def'，要转义的字符串内容
* @param type：true | false， 不传默认false，把特殊字符转实体字符
* @param codeArr：[]，指定要转义的特殊字符，比如只想转义单双引号，type=true那么这个数组就传['"',"'"]，false就传['&quot;','&apos;']
*
* * 如果type=false，则把特殊字符转实体字符，如：'abc<def' => 'abc&lt;def'
* 如果type=true，则把实体字符转特殊字符，如：'abc&lt;def' => 'abc<def'
* */
var strEscapeCharacter  = function (str, type, codeArr) {
    if (!str) {
        return str;
    }
	str = String(str);
	var escape = {
			'&amp;': '&',
			// '&nbsp;': ' ', //正常字符转实体字符不加空格的，避免展示有问题
			'&lt;': '<',
			'&gt;': '>',
			'&quot;': '"',
			'&apos;': "'"
		},
		key = '',
		isLen = codeArr && codeArr.length;

	if (type) { //如果type是true，则把实体字符转为特殊字符
	    //只有实体字符转正常字符才加上空格的转义
		escape['&nbsp;'] = ' ';
		for (key in escape) {
			if (isLen) {
				if (codeArr.indexOf(key) !== -1 && str.indexOf(key) !== -1) {
					str = returnStringReplaceResult(str, key, escape[key]);
				}
			} else if (str.indexOf(key) !== -1) {
				str = returnStringReplaceResult(str, key, escape[key]);
			}
		}
	} else { //如果是false则把特殊字符转为实体字符
		for (key in escape) {
			if (isLen) {
				if (codeArr.indexOf(escape[key]) !== -1 && str.indexOf(escape[key]) !== -1) {
					str = returnStringReplaceResult(str, escape[key], key);
				}
			} else if (str.indexOf(escape[key]) !== -1) {
				str = returnStringReplaceResult(str, escape[key], key);
			}
		}
	}

	return str;
};

// 去除表情符
var emptyEmojiCode = function (text) {
	if (text && new RegExp(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F\uDE80-\udeff]|[\u2600-\u2B55]/ig).test(text)) {
		text = text.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F\uDE80-\udeff]|[\u2600-\u2B55]/ig, '');
	}
	return text;
};
// 去除表情符
var inputEmptyEmojiCode = function (obj) {
	var $obj = $(obj);
	$obj.val(emptyEmojiCode($obj.val()));
};

//深拷贝引用数据方法
var deepCopyDataFn = function (data) {
	if (typeof data === 'object' && data !== null && !(data instanceof jQuery)) {
		if (Object.prototype.toString.call(data) === '[object Array]') {
			var arr = [];
			for (var i = 0; i < data.length; i++) {
				arr.push(deepCopyDataFn(data[i]));
			}
			return arr;
		} else if (Object.prototype.toString.call(data) === '[object Object]') {
			var obj = {};
			for (var key in data) {
				obj[key] = deepCopyDataFn(data[key]);
			}
			return obj;
		}
	}
	return data;
};

// 拷贝 多张图片 方法
var deepCopyImagesFn = function (files) {
	var newFile = [];
	for (var j = 0; j < files.length; j++) {
		newFile.push(files[j]);
	}
	return newFile;
};

//获取一维的对象的key，多层对象的不处理
var getObjectKeys = function (obj, isSort, isNumber) {
	var keyArr = [];

	$.each(obj, function(i, j){
		keyArr.push(i);
	});
	if (isSort) {
		if (isNumber) {
			return keyArr.sort(function (a, b) {
				return +a - +b;
			});
		}
		return keyArr.sort();
	}
	return keyArr;
};
//获取一维的对象的value，多层对象的不处理
var getObjectValues = function (obj) {
	var valueArr = [];

	$.each(obj, function(i, j){
		valueArr.push(j);
	});
	return valueArr;
};


/*
* 异步加载js
* @param {Object} optionObj--配置对象
*     @param {String} optionObj.link--加载的js的url地址
*     @param {String|Number} optionObj.version--加载的js文件版本号
*     @param {Function} optionObj.call--js文件加载后的回调，回调会返回一个参数('success'||'error')
*     @param {Boolean} optionObj.async--js文件是要异步加载还是同步加载，true=异步加载(默认异步)，false=同步加载
*     @param {String} optionObj.class--给加载的script节点添加class
*     @param {String} optionObj.useNewFn--使用新的加载方法, true=使用新方法(js引两遍以上必须使用新方法,或调asyncLoadingJSFileNew）
* */
var asyncLoadingJSFile = function(optionObj){
	var link = optionObj.src,
        useNewFn = (optionObj.useNewFn && (typeof optionObj.useNewFn === 'boolean')) ? optionObj.useNewFn : false;
	//true=使用新方法，false=使用旧方法
    if (useNewFn) {
        asyncLoadingJSFileNew(optionObj);
        return;
    }
	if(link){
		var $allScript = $('script[src]'),
			isOnload = false;

		$.each($allScript, function(i, j){
			if (j.src && j.src.indexOf(link) !== -1) {
				isOnload = true;
				return false;
			}
		});
		if (isOnload) {
			typeof optionObj.call === 'function' && optionObj.call('success');
			return; //如果存在js则不再引入
		}
		var _script = document.createElement('script');

		if (!link.startWith('http')) {
			link = gitWinLocHref() + link;
		}
		if(optionObj.version) link += ('?v=' + optionObj.version);
		_script.type = 'text/javascript';
		_script.src = link;
		_script.async = (typeof optionObj.async === 'boolean') ? optionObj.async : true; //true=异步加载，false=同步加载
		if (optionObj.class) {
			_script.classList.add(optionObj.class);
		}
		document.getElementsByTagName('body')[0].appendChild(_script);

		_script.onload = function(){
			typeof optionObj.call === 'function' && optionObj.call('success');
		};
		_script.onerror = function(){
			typeof optionObj.call === 'function' && optionObj.call('error');
		};
	}
};
var linkObj = {},
    asyncLoadingJSFileNew = function(optionObj) {
        var link = optionObj.src,
            callBackFn = (optionObj.call && typeof optionObj.call === 'function') ? optionObj.call : null,
            async = (typeof optionObj.async === 'boolean') ? optionObj.async : true; //true=异步加载，false=同步加载;
        var $allScript = $('script[src]'),
            isOnload = false;
        $.each($allScript, function(i, j){
            if (j.src && j.src.indexOf(optionObj.src) !== -1) {
                isOnload = true;
                return false;
            }
        });

        if (isOnload && !linkObj[link]) { // 页面已经加载 对象没有（表示页面已经引入） -> 直接执行回调
            linkObj[link] = {
                loading: true,
                status: 'success'
            };
            if(callBackFn)callBackFn(linkObj[link].status);
        } else if (linkObj[link] && linkObj[link].loading && callBackFn) { // 已经加载完成过的直接执行回调
            callBackFn(linkObj[link].status);
        } else if (linkObj[link] && !linkObj[link].loading && callBackFn) {
            // 没有加载完成，将回调加入队列
            linkObj[link].callBackList.push(callBackFn);
        } else if (!linkObj[link]) { // 新的链接，创建script，并将回调加入队列
            var elem = document.createElement('script'),
                callBackList = [];
            elem.type = 'text/javascript';
            elem.src = optionObj.version ? (link + '?v=' + optionObj.version) : link;
			elem.async = (typeof optionObj.async === 'boolean') ? optionObj.async : true; //true=异步加载，false=同步加载
            if (optionObj.class) {
                elem.classList.add(optionObj.class);
            }
            if(callBackFn)callBackList.push(callBackFn);
            linkObj[link] = {
                loading: false,
                callBackList: callBackList
            };
			document.getElementsByTagName('body')[0].appendChild(elem);
            elem.addEventListener('load', function () {
                runCallBackFn(link, 'success');
            });
            elem.addEventListener('abort', function () {
                runCallBackFn(link, 'abort');
                console.warn('[load->abort]', link);
            });
            elem.addEventListener('error', function () {
                runCallBackFn(link, 'error');
                console.warn('[load->error]', link);
            });
        }
    },
	runCallBackFn = function(link, status) {
        var list = linkObj[link].callBackList;
        linkObj[link].loading = true;
        linkObj[link].status = status;
        for(var i = list.length; i--; (i > -1)) {
            var call = list[i];
            if (typeof call === 'function') {
                call(status);
                list.splice(i, 1);
            }
        }
    };

/*
* 异步加载CSS
* @param {Object} optionObj--配置对象
*     @param {String} optionObj.link--加载的css的url地址
*     @param {String|Number} optionObj.version--加载的css文件版本号
*     @param {Function} optionObj.call--css文件加载后的回调，回调会返回一个参数('success'||'error')
*     @param {Boolean} optionObj.async--css文件是要异步加载还是同步加载，默认异步
*     @param {String} optionObj.class--给加载的link节点添加class
* */
var asyncLoadingCssFile = function(optionObj){
	var link = optionObj.src;
	if(link){
		var $allLink = $('link[href]'),
			isOnload = false;

		$.each($allLink, function(i, j){
			if (j.href && j.href.indexOf(link) !== -1) {
				isOnload = true;
				return false;
			}
		});
		if (isOnload) {
			typeof optionObj.call === 'function' && optionObj.call('success');
			return; //如果存在js则不再引入
		}
		var _link = document.createElement('link');

		if (!link.startWith('http')) {
			link = gitWinLocHref() + link;
		}
		if(optionObj.version) link += ('?v=' + optionObj.version);
		_link.type = 'text/css';
		_link.rel = 'stylesheet';
		_link.href = link;
		_link.async = (typeof optionObj.async === 'boolean') ? optionObj.async : true; //true=异步加载，false=同步加载
		if (optionObj.class) {
			_link.classList.add(optionObj.class);
		}
		document.getElementsByTagName('head')[0].appendChild(_link);

		_link.onload = function(){
			typeof optionObj.call === 'function' && optionObj.call('success');
		};
		_link.onerror = function(){
			typeof optionObj.call === 'function' && optionObj.call('error');
		};
	}
};


//移除外部插件插入节点
var removeChromeAppendDom = function () {
	var stoId = setTimeout(function () {
		clearTimeout(stoId);
		stoId = null;
		if ($('[id*="fatkun"]').length) {
			$('[id*="fatkun"]').remove();
		}

		var $style = $('style');
		$.each($style, function(i, j){
			if ($(j).html().indexOf('ant-') !== -1 || $(j).html().indexOf('.progress--') !== -1) {
				$(j).remove();
			}
		});
	}, 5000);
};
$(function () {
	removeChromeAppendDom();
});


/**
 * 防连点验证
 * 注意点：1、进入请求方法时就得先加防连点锁定；
 *        2、必填验证未通过的if条件里面需要解除防连点锁定；
 *        3、请求需要加error失败函数，success函数和error函数里面也需要解除防连点锁定
 * 使用例子：
 * var aaa = function() {
 *   var $saveBtn = $('#xxx') || $('#xxx, .xxx') || [$('#xxx'), $('.xxx')]; //能够触发aaa方法的节点(可能会有多个节点，可以传个数组jq对象)，调用aaa方法时需要把该节点禁止点击，防止再次触发aaa方法
 *   //设置防连点锁定，如果返回true则在锁定状态，直接return
 *  if (evenThePointVerify('setEvenThePoint', true, $saveBtn)) return;
 *  var shopId = $('#shopId').val();
 *
 *  if (!shopId) {
 *     //解除防连点锁定
 *     evenThePointVerify('setEvenThePoint', false, $saveBtn)
 *     $.fn.message({type:'error', msg: '请选择店铺'});
 *     return false;
 *  }
 *
 *  $.ajax({
 *    type:'POST',
 *    url:xxx,
 *    success:function(data){
 *       //解除防连点锁定
 *       evenThePointVerify('setEvenThePoint', false, $saveBtn)
 *    },
 *    error: function(){
 *      //解除防连点锁定
 *      evenThePointVerify('setEvenThePoint', false, $saveBtn)
 *    }
 *  })
 * }
 * */
var evenThePointVerify = (function () {
	var evenThePointVerifyObj = {};
	/**
	 * @param key 需要记录防连点的key名
	 * @param value 是需要设置防连点还是解除防连点锁定状态，true为设置锁定，false为解除锁定
	 * @param $domArr 需要加禁止点击的节点，可以直接传$('xxx')jq对象进来，也可以传[$('xxx'), $('xxx')]数组jq对象
	 * @return true|false 返回true则说明当前key的防连点属于锁定状态不可以请求，返回false则说明当前key的防连点属于未锁定状态可以请求
	 * */
	return function (key, value, $domArr) {
		if ($domArr && $domArr.length) { //如果jq对象存在
			//循环jq对象，根据传的value去禁止或者解除禁止点击
			$.each($domArr, function(i, j){
				//pointer-events=none的话则该节点无法触发事件
				// $(j).css('pointer-events', value ? 'none' : '');
				$(j)[value ? 'addClass' : 'removeClass']('no-pointer');
			});
		}
		//如果对象中当前key的值为false或者不存在
		if (!evenThePointVerifyObj[key]) {
			//设置当前key对应的值
			evenThePointVerifyObj[key] = value; //这里的value肯定是true
			return false; //返回false，说明当前的防连点状态属于未锁定
		} else { //如果对象中当前key的值为true，则说明当前设置的防连点锁定还未解除，不允许走后面的请求
			//设置当前key对应的值
			if (value) { //如果value是true，则是属于锁定状态
				evenThePointVerifyObj[key] = value; //继续保持锁定状态
			} else { //如果value是false，则是需要解除锁定
				delete evenThePointVerifyObj[key]; //把当前对象的key移除
			}
			//因为解除锁定时也会走else，但是value传false解除锁定时不需要禁止后面的逻辑执行，所以这个时候返回true也无所谓
			return true; //返回true，说明当前的防连点状态属于锁定
		}
	};
})();


/**
 * 格式化json并展示
 *
 *
 **/
var formatJsonForNotes = function(json, options) {
	var reg = null,
		formatted = '',
		pad = 0,
		PADDING = '  '; // （缩进）可以使用'\t'或不同数量的空格
	// 可选设置
	options = options || {};
	// 在 '{' or '[' follows ':'位置移除新行
	options.newlineAfterColonIfBeforeBraceOrBracket = (options.newlineAfterColonIfBeforeBraceOrBracket === true) ? true : false;
	// 在冒号后面加空格
	options.spaceAfterColon = (options.spaceAfterColon === false) ? false : true;
	// 开始格式化...
	if (typeof json !== 'string') {
		// 确保为JSON字符串
		json = JSON.stringify(json);
	} else {
		//已经是一个字符串，所以解析和重新字符串化以删除额外的空白
		json = JSON.parse(json);
		json = JSON.stringify(json);
	}
	// 在花括号前后添加换行
	reg = /([\{\}])/g;
	json = json.replace(reg, '\r\n$1\r\n');
	// 在方括号前后添加新行
	reg = /([\[\]])/g;
	json = json.replace(reg, '\r\n$1\r\n');
	// 在逗号后添加新行
	reg = /(\,)/g;
	json = json.replace(reg, '$1\r\n');
	// 删除多个换行
	reg = /(\r\n\r\n)/g;
	json = json.replace(reg, '\r\n');
	// 删除逗号前的换行
	reg = /\r\n\,/g;
	json = json.replace(reg, ',');
	// 可选格式...
	if (!options.newlineAfterColonIfBeforeBraceOrBracket) {
		reg = /\:\r\n\{/g;
		json = json.replace(reg, ':{');
		reg = /\:\r\n\[/g;
		json = json.replace(reg, ':[');
	}
	if (options.spaceAfterColon) {
		reg = /\:/g;
		json = json.replace(reg, ': ');
	}
	$.each(json.split('\r\n'), function(index, node) {
		var i = 0,
			indent = 0,
			padding = '';
		if (node.match(/\{$/) || node.match(/\[$/)) {
			indent = 1;
		} else if (node.match(/\}/) || node.match(/\]/)) {
			if (pad !== 0) {
				pad -= 1;
			}
		} else {
			indent = 0;
		}
		for (i = 0; i < pad; i++) {
			padding += PADDING;
		}
		formatted += padding + node + '\r\n';
		pad += indent;
	});
	return formatted;
};


/*
* 可编辑节点绑定事件触发方法
* */
$.fn.extend({
	contentEdit: function(){
		var $that = $(this);

		$that.off('click').on('click', function(){
			$(this).closest('.form-component').addClass('form-focus');
		});
		$that.off('blur').on('blur', function(){
			this.scrollLeft = 0;
			$(this).closest('.form-component').removeClass('form-focus');
		});
		//可编辑节点输入事件
		$that.off('input').on('input', function(){
			//每次输入会默认生成一个span节点，只取text纯文本内容，然后重新赋值一次，去除掉span节点
			$(this).text($(this).text());
			//设置contenteditable属性的可编辑节点，重新赋值内容后光标会跑到前面去，需要把光标设置到最后面
			setSelectionFn(this);
		});
	}
});


/*
* 全局产品按页导出方法
* 使用该方法，需要在页面中导入邮箱验证文件 emailVerifyModal.jsp
* 使用commonProductExportByPage.open()方法打开弹层时传入导出的接口url、参数、页面列表的总页数
* @open(param) option 配置对象
* @open(param) option.url 导出的接口url
* @open(param) option.totalPage 当前页面列表的总页数，若不传默认从#totalPage节点中获取
* @open(param) option.pageSize 当前页面列表每页的条数，若不传默认从#pageSize节点中获取
* @open(param) option.params 导出参数
* */
var commonProductExportByPage = (function () {
	var $commonProductExportByPageModal = $('#commonProductExportByPageModal'),
		url = '',
		totalPage = 0,
		pageSize = 0,
		pageExportMaxNum = 1000,
		emailVerify = $('#emailVerify').val(),
		params = {};

	var removeRecord = function () {
		$commonProductExportByPageModal.find('input[name="commonProductExportByPageNumbers"]').val('');
	};

	return {
		open: function (options) {
			url = options.url;
			totalPage = +options.totalPage || +$('#totalPage').val();
			pageSize = +options.pageSize || +$('#pageSize').val();
			params = options.params;
			pageExportMaxNum = +options.pageExportMaxNum || options.pageExportMaxNum;
			emailVerify = $('#emailVerify').val();
			$commonProductExportByPageModal = $('#commonProductExportByPageModal');

			// 邮箱验证
			// 判断用户是否开启邮箱验证
			if (emailVerify === 'true') {
				$('#commonProductExportByPageSpan').css('margin-right','266px').html('<a href="sys/index.htm?go=m482">关闭邮箱验证</a>');
			} else {
				$('#commonProductExportByPageSpan').css('margin-right','112px').html('<a href="sys/index.htm?go=m482">开启邮箱验证</a>，让您导出店铺数据更安全');
			}

			$commonProductExportByPageModal.modal('show');
		},
		confirm: function () {
			var pageNo = $.trim($('#commonProductExportPageNo').val()),
				startNo = 0,
				curPageSize = pageSize,
				endNo = 1;

			if (!pageNo) {
				MYJ.message.error('请填写需要导出的页数！');
				return;
			}

			if (pageNo.indexOf('-') > -1) {
				var arr = pageNo.split('-');
				if(isNaN(arr[0]) || isNaN(arr[1])){
					MYJ.message.error('请输入有效的页数！');
					return;
				}
				startNo = parseInt($.trim(arr[0]));
				endNo = parseInt($.trim(arr[1]));
				if (!startNo || !endNo || endNo < startNo) {
					MYJ.message.error('请输入有效的页数！');
					return;
				}
				if (startNo < 0 || endNo < 0 || startNo > totalPage || endNo > totalPage) {
					MYJ.message.error('请输入有效的页数！');
					return;
				}
			} else {
				if (isNaN(pageNo)){
					MYJ.message.error('请输入有效的页数！');
					return;
				}
				startNo = parseInt($.trim(pageNo));
				if(!startNo || startNo < 0 || startNo > totalPage){
					MYJ.message.error('请输入有效的页数！');
					return;
				}
				endNo = 0;
			}

			if (!curPageSize) {
				curPageSize = 50;
			}

			startNo = startNo < 1 ? 0 : startNo - 1;//纠正计算数据条数不对的问题
			if (endNo) curPageSize = endNo * curPageSize - startNo * curPageSize;

			if(curPageSize > 1000){
				MYJ.message.error('暂时只支持最大导出1000个产品！');
				return;
			}

			params['pageSize'] = pageSize;
			params['pageNo'] = pageNo;

			$commonProductExportByPageModal.modal('hide');
			//清空记录
			removeRecord();
			// 如果用户开启了邮箱验证，弹出验证框
			if (emailVerify === 'true') {
				// 给验证按钮注册事件
				$('#verifyCodeBtn').unbind('click');
				$('#verifyCodeBtn').bind('click', verifyEmailCode(params, this.export));
				// 弹出验证框
				$('#verifyCode').val('');
				$('#verifyEmailCodeModal').modal('show');
			} else {
				this.export(params);
			}
		},
		export: function (params) {
			batchExportData(url, params,'产品',pageExportMaxNum);
		},
		close: function () {
			$commonProductExportByPageModal.modal('hide');
			//清空记录
			removeRecord();
		},

	}
})()

/**
 *  去除气泡内容中的script脚本
 *  @param str 要去除包含script字段的字符串内容
 *  @return str 返回去除script字段后的字符串内容
 **/
var removeScriptContent = function (str) {
	var startIndex = str.indexOf('<script'),
		endIndex = str.indexOf('</script>');
	if(startIndex !== -1 && endIndex !== -1){ //判断是否有script脚本
		str = str.substring(0, startIndex) + str.substring(endIndex + 9);
		if(str.indexOf('<script') !== -1){
			return removeScriptContent(str);
		}
	}
	return str;
};

// 全局公共方法
(function ($) {
    var MyjCla = function () {};
	window.MYJ = new MyjCla();

	MyjCla.prototype.loading = {
	    show: function(){
            $('#loading').modal('show');
        },
        hide: function() {
            $('#loading').modal('hide');
        }
    };


    //统计请求ajax的次数，调用一次请求则+1，请求完成则-1，只有值等于0的时候才关闭loading，防止部分请求没完成然后部分完成了，loading关了之后用户可以操作页面
    var myjAjaxCloseLoading = 0,
		locHref = gitWinLocHref();
    /** @description 完整例子：
     * 使用该封装ajax不需要在ajax之前去写$('#loading').modal('show')了
     * 也不需要在成功回调或者失败回调里面关闭loading弹层，在封装里面默认有做处理
     * MYJ.ajax({
     *     以下三个为必传参数
     *     url: 'xxx.json', //请求地址
     *     data: {xxx:'xxx'}, //请求参数
     *     success: function(data) {...} //成功回调
     *
     *     以下为非必传参数
     *     type: 'GET', //不传默认是POST
     *     dataType: 'html', //不传默认是json
     *     async: false, //是否同步请求，不传或者传true默认异步请求，传false为同步请求
     *     contentType: 'application/json' //请求体类型，一般是后端需要的请求参数为json字符串时设置，默认不需要设置
     *     error: function(){}, //失败回调，不传该字段时，请求失败默认会报错小黄条“网络异常，请稍后重试！”，传了失败回调时则不会报错小黄条，需要报错则自己在回调里面调用小黄条报错
     *     complete: function(){}, //请求结束后的回调
     *     loading: false, //是否显示loading弹层，不传或者传true默认显示，传false不显示
     *     pointKey: 'saveKey', //设置\解除防连点检测的key名，不传默认不设置防连点
     *     pointDom: $('.xxx') || [$('.xx1'), $('.xx2')], //设置\解除防连点检测限制点击的jq对象节点,也可以是数组jq对象节点
     * });
     **/
    /**
	 * @description 公用封装ajax请求
	 * @description 方法入参
	 * @param {Object} optionObj--配置对象
	 *     必传配置参数
	 *     @param {string} optionObj.url--请求地址
	 *     @param {Object} optionObj.ajaxData--请求参数，默认是传对象，如果设置了contentType='application/json'，则需要传json字符串
	 *     @param {Function} optionObj.success--成功回调
	 *     剩余非必传配置对象，需要就传，不需要就不用传
	 *     @param {string} optionObj.type--请求类型：POST || GET， 默认POST
	 *     @param {string} optionObj.dataType--返回数据类型：json || html，传了则按传的来，如果没传则优先截取请求url的后缀来判断，.htm则是html，其它都默认json
	 *     @param {string} optionObj.async--请求是否需要异步执行，true或者不传则异步(默认)，false同步
	 *     @param {string} optionObj.contentType--请求体类型 'application/json'，默认空，如果是application/json则请求参数data需要是json字符串传给后端
	 *     @param {Function} optionObj.error--失败回调
	 *     @param {Function} optionObj.complete--请求结束后的回调
	 *     @param {Boolean} optionObj.loading--是否展示loading弹层，true展示(默认)，false不展示
	 *     @param {string} optionObj.pointKey--设置\解除防连点检测的key名，不传默认不设置防连点
	 *     注意：如果一个页面有多个请求需要做防连点限制，那么每个请求传进来的key名一定要不一样，
	 *           避免同时调用两个请求，第二个请求因为第一个请求未结束，防连点未解除而导致无法被调用

	 *     @param {dom} optionObj.pointDom--设置\解除防连点检测限制点击的jq对象节点,也可以是数组jq对象节点，比如：$('xxx') || [$('xxx'), $('xxx')]
	 **/
	MyjCla.prototype.ajax = function(optionObj) {
		var pointKey = '', //防连点的key
			pointDom = ''; //防连点的dom节点

		//赋值防连点的key
		if (optionObj.pointKey) pointKey = optionObj.pointKey; //防连点的key
		//赋值防连点的dom节点
		if (optionObj.pointDom) pointDom = optionObj.pointDom; //防连点的dom节点
		//设置防连点
		if (pointKey && evenThePointVerify(pointKey, true, pointDom)) return;

		var $loading = $('#loading'),
			isLoading = true, //是否需要loading弹层
            url = optionObj.url.replace(/^\//,''); //请求url

		if (!url.startWith('http')) {
			url = locHref + url;
		}

		var ajaxObj = {
				type: 'POST', //请求类型，默认post
				url: url, //请求url
				data: optionObj.data || {}, //请求参数
				success: function(data){
					//解除防连点和关闭loading不能放到complete函数事件中执行，得在成功或失败的回调方法之前先执行，防止回调方法里面代码报错，报错后不会执行complete事件
					//解除防连点
					pointKey && evenThePointVerify(pointKey, false, pointDom);
					if (isLoading) { //如果需要显示loading弹层
                        myjAjaxCloseLoading--; //计数-1，用来判断是否可以关闭loading弹层
                        //如果数量=0了，则说明当前所有请求都执行完了，可以关闭loading
                        if (!+myjAjaxCloseLoading) {
                            $loading.modal('hide');
                        }
                    }
					if(typeof optionObj.success === 'function'){
						optionObj.success(data);
					}
				},
				error: function(err){
					//解除防连点和关闭loading不能放到complete函数事件中执行，得在成功或失败的回调方法之前先执行，防止回调方法里面代码报错，报错后不会执行complete事件
					//解除防连点
					pointKey && evenThePointVerify(pointKey, false, pointDom);
                    if (isLoading) { //如果需要显示loading弹层
                        myjAjaxCloseLoading--; //计数-1，用来判断是否可以关闭loading弹层
                        //如果数量=0了，则说明当前所有请求都执行完了，可以关闭loading
                        if (!+myjAjaxCloseLoading) {
                            $loading.modal('hide');
                        }
                    }
					if(typeof optionObj.error === 'function'){
						optionObj.error(err);
					}else{
						MYJ.message.error('网络异常a，请稍后重试！');
					}
				},
				complete: function (XMLHttpRequest, status) { //请求结束后调用的函数事件
					if(typeof optionObj.complete === 'function'){
						optionObj.complete(XMLHttpRequest, status);
					}
				}
			};

		//移除url和data参数
		delete optionObj.url;
		delete optionObj.data;
		$.each(optionObj, function(i, j){
			//只有不等于三个回调函数才进入
			if (i !== 'success' && i !== 'error' && i !== 'complete') {
				//如果是loading
				if (i === 'loading') {
					//是否展示loading弹层，如果有值则用传进来的值
					isLoading = j;
				} else { //其它参数
					// if (i === 'contentType' && j === 'json') j = 'application/json';
					ajaxObj[i] = j;
				}
			}
		});

		if (!optionObj.dataType) { //如果dataType没传
		    //判断请求url的后缀是否是.htm，不能判断结尾相等，有的get请求可能把参数带在url上了
            if (url.indexOf('.htm') !== -1) {
                ajaxObj.dataType = 'html'; // 返回数据类型，设置接收html数据
            } else { //如果不是htm结尾，则统一归为json
                ajaxObj.dataType = 'json'; // 返回数据类型，设置接收json数据
            }
        }

		if (isLoading) { //如果需要显示loading弹层
            $loading.modal('show');
            myjAjaxCloseLoading++; //计数+1，用来判断是否可以关闭loading弹层
        }
		return $.ajax(ajaxObj);
	};

	MyjCla.prototype.message = function(data) {
		return $.fn.message(data);
	};
	MyjCla.prototype.message.error = function(msg, isText) {
		MYJ.message({type: 'error', msg: msg, isText: isText === undefined ? true: isText, existTime: 3000});
	};
	MyjCla.prototype.message.success = function(msg) {
		MYJ.message({type: 'success', msg: msg, isText: true, existTime: 3000});
	};
	MyjCla.prototype.extend = function(key, value) {
		key = key.split('.');

		var key1 = key.shift(),
			key2 = key.length ? key.shift() : null;

		if (key2) {
			var o = Object.create(this);
			Object.defineProperty(o, key2, {
				value: value,
				writable: false
			});
			if (this.hasOwnProperty(key1)) {
				Object.defineProperty(this[key1], key2, {
					value: value,
					writable: false
				})
			} else {
				Object.defineProperty(this, key1, {
					value: o,
					writable: false
				})
			}
		} else {
			Object.defineProperty(this, key1, {
				set: function(v){
					return value;
				},
				get: function(){
					return value;
				}
			});
		}
	};

    /**
     *重置分类
     */
    MYJ.extend('resetCategory', function($outEL) {
        $outEL.find('#searchCategory').val('');
        $outEL.find('.classifie-search').addClass('hide');
        $outEL.find('.categoryChooseOutDiv, .categoryChooseCrumbs').removeClass('hide');
        var $categoryChooseInDiv = $outEL.find('div.categoryChooseInDiv');
        $categoryChooseInDiv.find('div.serch input').val('').trigger('keyup');
    });


    /**
     * 只检查店小秘插件，是否安装，是否开启，版本比较，是否谷歌环境
     * @param options ={version: 2.1.52}
     * @param callback(true|false, error)
     */
    var app = {
        install: false,
        version: '',
        isCheck: false
    };

    function checkPlugin(options, callback){
        this.options = options;
        this.check = function(){
            this.checkProvide();
        };
        this.setCheck = function(res) {
            app.isCheck = !res.code;
            callback(res, app);
        };
        this.checkProvide = function() {
            if (typeof chrome != 'undefined' && chrome.runtime) {
                this.checkInstall();
            } else {
                this.setCheck({code: 1001, msg: '未在谷歌浏览器运行或未开启插件'});
            }
        };
        this.checkInstall = function() {
            var _this = this;

            if (_this.options.version) {
                app.install = true;
                _this.checkVersion();
            } else {
                _this.setCheck({code: 0, data: 1});
            }
        };
        this.checkVersion = function() {
            var _this = this,
                outInt = 0;

            // {platform: 'getAppVersion'} 通过插件获取当前插件的安装版本，此功能在插件2.1.52版本添加
            chrome.runtime.sendMessage('ioadaikpljilagoddljnamloiebcoopb', {platform: 'getAppVersion'}, function(res){
                clearTimeout(outInt);
                if (res && res.code === 0) {
                    var curV = parseInt(_this.options.version.replace(/\./g, '')),
                        onlineVersion = parseInt(res.data.replace(/\./g, ''));

                    if (curV < onlineVersion) {
                        app.version = res.data;
                        _this.setCheck({code: 0, data: 1});
                    } else {
                        _this.setCheck({code: 1003, msg: '您当前未安装采集插件或采集插件不是最新版，请安装最新版<a href="' + DXM_HELP_URL + '/pre/getContent.htm?id=170" target="_blank">采集插件</a>'});
                    }
                } else {
                    _this.setCheck({code: 1003, msg: '您当前未安装采集插件或采集插件不是最新版，请安装最新版<a href="' + DXM_HELP_URL + '/pre/getContent.htm?id=170" target="_blank">采集插件</a>'});
                }
            });
            // 在插件2.1.52之前版本得不到回调，所以通过一个定时来做判断
            outInt = setTimeout(function () {
                if (!app.version) {
                    _this.setCheck({code: 1003, msg: '您当前未安装采集插件或采集插件不是最新版，请安装最新版<a href="' + DXM_HELP_URL + '/pre/getContent.htm?id=170" target="_blank">采集插件</a>'});
                }
            }, 1000);
        }
    }
    MYJ.extend('checkPlugin', function(o, callback) {
        var ins = new checkPlugin(o, callback);
        ins.check();
    });

    MYJ.extend('DXMPlugin', {
        pluginId: 'ioadaikpljilagoddljnamloiebcoopb',
        /**
         * 向店小秘插件后台发送消息
         * @param message 发送的内容
         * @param callback 后台响应后的回调
         */
        send: function(message, callback){
            try {
                chrome.runtime.sendMessage(this.pluginId, message, function(){
                    callback.apply(callback, arguments);
                });
            } catch (e) {
                // callback.apply(callback, "");
                // throw e;
            }
        }
    });


    /**
     * 事件注册中心，主要用来通过注册订阅来做回调，这样集中管理，只需要暴露出去有限的API，让第三方监听接口做相应的逻辑即可
     * 不满足时，我们只需要扩展另一个api即可，使用者只需要重新注册这个接口做相应的逻辑就行，不在往参数里面添加各种各样的回调
     * 缺点：1.目前在注册中心没有引入Id的身份，如果有身份系统就可以通过Id只触发自己，2.一个接口目前只支持一个注册，未来有需要可以一个接口可以多个注册，并且支持id做更细分的场景。
     * 用法：
     * var event = new MYJ.Mevent();
     * Obj = {
     *     on: function(k, f) { // 接收注册
     *         event.on(k, f);
     *     },
     *     say: function() {// 做内部的事
     *         event.trigger('hello', '你好，世界！'); // 触发接口 hello 回调，
     *     }
     * }
     * Obj.on("hello", function(msg){ // 做自己的事
     * });
     * Obj.say();
     * @constructor
     */
    function MEvent() {
        this.registry = {};
        this.trigger = function(k) {
            var args = [];
            for (var i = 1; i < arguments.length; i++) {
                args.push(arguments[i]);
            }
            return this.registry[k] && this.registry[k].apply(this.registry[k], args);
        };
        this.on = function(k, v) {
            this.registry[k] = v;
        };
        this.off = function(k) {
            delete this.registry[k];
        }
    }

    MYJ.extend('MEvent', MEvent);

    /**
     * Bootstrap 模态框
     * 应当更多的利用bootstrap的本身modal的能力。
     * 用法：
     * var modal = MYJ.bootModal.create({
     *     title: "Hello"
     * });
     * modal.on("show", function(){
     * });
     * modal.on("hide", function(){
     * });
     * modal.on("confirm", function(){ // 如果 return true；可以阻止模态框关闭
     * });
     * modal.on("cancel", function(){
     * });
     * modal.on("close", function(){ // 如果 return true；可以阻止模态框关闭
     * });
     * modal.show() 显示;
     * modal.hide([true]) 隐藏，如果传入参数true，会隐藏后销毁modal元素;
     * 简化页面模态框的静态文本，id命名，嵌套modal，免去在jsp页面一个一个的加，只关注业务逻辑
     * 后期可以利用handlebars.js模板引擎，来在模板里面做更多的逻辑处理
     * @param {[type]}
     */
    function BootstrapModal(o) {
        this.event = new MEvent();
        this.isDestory = false;
        this.config = {
            title: '操作', // 标题
            template: null, // 内容，
            url: null, // 通过远程地址获取内容，template 字段优先级高，如果template字段内容不为空，会使用template字段的值作为内容
            width: '', // 模态框的宽度
            backdrop: false, // true|false 背景是否支持可点击关闭
            destroy: true, // true|false 关闭后是否销毁模态框元素
            auto: true, // true|false 是否自动，目前只用来做自动显示模态框
            id: '', // modal 元素的id
            className: 'modal-new', // modal 元素的扩展class类
            bodyClass: '',
            button: { // 暂时没有做处理
                confirm: {
                    show: true,
                    text: "确定",
                    className: 'button btn-determine',
                    click: function(){}
                },
                cancel: {
                    show: true,
                    text: "关闭",
                    className: 'button btn-gray m-left12',
                    click: function(){}
                }
            },
			buttonTips: '', // 底部操作区域提示语
            footer: '', // 如果有值则由用户接管底部操作
            load: function(){}, // 内容插入到节点后的回调
            success: function(result, closeStatus) {}, // 不再使用，通过on注册中心代替
            close: function(status) { // 不再使用，通过on注册中心代替
                // 返回 true 阻止关闭，返回 false 不返回 默认关闭
            }
        };
        for (var k in o) {
            if (this.config.hasOwnProperty(k)) {
                if (k === 'button') {
                    for (var bk in o[k]) {
                        if (this.config[k].hasOwnProperty(bk)) {
                            for (var bvk in o[k][bk]) {
                                if (this.config[k][bk].hasOwnProperty(bvk)) {
                                    this.config[k][bk][bvk] = o[k][bk][bvk];
                                }
                            }
                        }
                    }
                } else {
                    this.config[k] = o[k];
                }
            }
        }

        this.closeStatus = false;
        this.status = false;
        // jquery 元素对象
        this.elems = {
            modal: null,
            title: null,
            body: null,
            confirm: null,
            close: null,
            iconClose: null,
            backdrop: null
        };

        this.init = function() {
            this.create();
            this.setElems();
            this.setBind();
            this.setData();
            (!this.config.url && this.config.auto) && this.show();
        };

        this.create = function() {
            var elem = document.createElement('div'),
                elemHtml = '',
                style = '';

            if (this.config.width) style += 'width:' + this.config.width;

            elem.setAttribute('data-backdrop', 'static');
            elem.id = this.config.id;
            elem.className = this.config.className + ' modal';

            /**
             * Bsm = bootstrap modal
             */
            elemHtml += '<div class="modal-dialog" style="' +style+ '">' +
                '           <div class="modal-content"><div class="modal-header">' +
                '                <button type="button" class="close iconCloseBsm"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>' +
                '                <h4 class="modal-title modalTitleBsm"></h4>' +
                '            </div>' +
                '            <div class="modal-body ' +this.config.bodyClass+ ' modalBodyBsm">' +
                '            </div>' +
                '           <div class="modal-footer">';

            if (this.config.footer) {
                elemHtml += this.config.footer;
            } else {
				elemHtml += '<div class="flex-align-center f-left"><div class="flex-1">'+this.config.buttonTips+'</div><div>';
				elemHtml += this.config.button.confirm.show ? '<button type="button" class="' +this.config.button.confirm.className+ ' btnConfirmBsm">' +this.config.button.confirm.text+ '</button>' : '';
				elemHtml += '<button type="button" class="' +this.config.button.cancel.className+ ' btnCloseBsm">' +this.config.button.cancel.text+ '</button>';
				elemHtml += '</div></div>';
            }
            elemHtml += '</div></div></div>';

            elem.innerHTML = elemHtml;
            $('body').append(elem);
            this.elems.modal = $(elem);
        };

        this.getElem = function(k) {
            return this.elems[k];
        };

        this.setElems = function() {
            this.elems.title = this.elems.modal.find('.modalTitleBsm');
            this.elems.body = this.elems.modal.find('.modalBodyBsm');
            this.elems.confirm = this.elems.modal.find('.btnConfirmBsm');
            this.elems.close = this.elems.modal.find('.btnCloseBsm');
            this.elems.iconClose = this.elems.modal.find('.iconCloseBsm');
        };

        this.setData = function() {
            var _this = this;
            this.elems.title.text(this.config.title);
            if (this.config.template !== null) {
                this.elems.body.html(this.config.template);
                this.config.load();
            } else if (this.config.url !== null) {
                MYJ.ajax({
					type: 'GET',
                    url: this.config.url + '?v=1.0.1',
                    dataType: 'html',
                    loading: false,
                    success: function(res) {
                        _this.elems.body.html(res);
                        _this.config.load();
                        _this.config.auto && _this.show()
                    }
                });
            }
        };

        this.setBind = function() {
            var that = this;
            this.elems.confirm.on('click', function(ev) {
                that.onConfirm();
            });

            this.elems.close.on('click', function(ev){
                that.event.trigger('cancel');
                that.onClose();
            });
            this.elems.iconClose.on('click', function(ev){
                that.onClose();
            });

            if (this.config.backdrop) {
                this.elems.backdrop = this.elems.modal.find('.modal-backdrop');
                this.elems.backdrop.off('click').on('click', function(ev){
                    that.onClose();
                });
            }
        };

        this.onConfirm = function() {
            // 在auto模式下，触发confirm事件，返回值true才有效阻止关闭，无返回true，才会自动关闭，其它情况都需要手动关闭，为阻止
            var r = this.event.trigger('confirm', true);
            // !r && this.hide('confirm');
            (!r && this.config.auto) && this.hide('confirm');
        };

        this.onClose = function() {
            //如果返回true 阻止关闭
            var r = this.event.trigger('close');
            !r && this.hide('close');
        };

        this.hide = function(type) {
            this.closeStatus = true;
            this.elems.modal.modal('hide');
            this.event.trigger('hide', type);
            this.config.destroy && this.destory();
        };

        this.show = function() {
            this.elems.modal.modal('show');
            this.event.trigger('show');
        };

        this.destory = function() {
            this.elems.modal.remove();
            this.isDestory = true;
        };

        this.init();
    }
    // modal template render

    var bootModal = {
        create: function(o) {
            var instance = new BootstrapModal(o);
            return {
                elem: instance.getElem('modal'),
                /**
                 * 开放的接口
                 * 订阅名 | 值 | 说明
                 * show | function():void | 显示事件
                 * hide | function():void | 隐藏事件
                 * confirm || 确认按钮被触发
                 * cancel || 取消按钮被触发
                 * close || 关闭事件触发
                 * @param k
                 * @param v
                 */
                on: function (k, v) {
                    instance.event.on(k ,v);
                    if (k === 'show' && instance.config.auto) instance.event.trigger(k);
                },
                hide: function(r) {
                    instance.hide();
                    if (r) {
                        instance.destory();
                        instance = null;
                    }
                },
                show: function() {
                    if (instance.isDestory) {
                        console.error('this modal is destroyed');
                    } else {
                        instance.show();
                    }
                },
                destory: function() {
                    instance.destory();
                    instance = null;
                }
            }
        }
    };
    MYJ.extend('bootModal', bootModal);


    if (!String.prototype.escapeHtml) {
        /**
         * 实体化标签
         * @returns {string}
         */
        String.prototype.escapeHtml = function(codeArr) {
            return strEscapeCharacter(this, false, codeArr);
        }
    }
    if (!String.prototype.unEscapeHtml) {
        /**
         * 实体化标签
         * @returns {string}
         */
        String.prototype.unEscapeHtml = function(codeArr) {
            return strEscapeCharacter(this, true, codeArr);
        }
    }
    MYJ.extend('escapeHtml', function(str, codeArr){
        return str.escapeHtml(codeArr);
    });
    MYJ.extend('unEscapeHtml', function(str, codeArr){
        return str.unEscapeHtml(codeArr);
    });

    /**
     * 去除html标签
     * t = true|false true 移除标签， false 保留标签的内容
     */
    MYJ.extend('filterHtmlTag', function(str, t){
        var reg = t ? new RegExp(/<[^>]*>/g): new RegExp(/<\/?[^>]*>/g);
        return str.replace(reg, '');
    });

    /**
     * ['/','\\\\', "'", '"', '%', '_']
     * @param str 要转义的字符串
     * @param charArr 自定义转义的字符数组
     * @param callback callback(match 匹配到的字符, replaceStr 替换后的字符)自定义替换值回调
     * @returns 转义后的值
     */
    function _escapeChar(str){
        var regPattern = ['\\\\'], // 匹配的规则，其它的以后用到再加，个别的可以通过自定义的形式和回调来完成，这里用4个是因为声明的字符串会解析成\\\\=\\两个
            reg = '',
            charArr = [], // 自定义匹配字符
            callback = null; // 回调方法

        // 如果只有2个参数，arr|func，如果是arr为自定义匹配字符，如果是func为回调方法
        if (arguments.length === 2) {
            charArr = Array.isArray(arguments[1]) ? arguments[1]: [];
            callback = typeof arguments[1] === 'function' ? arguments[1]: null;
        }

        if (arguments.length === 3) {
            charArr = Array.isArray(arguments[1]) ? arguments[1]: [];
            callback = typeof arguments[2] === 'function' ? arguments[2]: null;
        }

        // 联合本身匹配字符和自定义匹配字符
        regPattern = regPattern.concat(charArr);
        // 组装正则表达式 (\\|/|'|\"|%)
        regPattern = '(' + regPattern.join('|') + ')';
        reg = new RegExp(regPattern, 'mg');
        return str.replace(reg, function(match, offset, strObj){
            var nVal = '\\' + match,
                r = null;
            // 模糊匹配
            if (match === '\\') {
                // nVal += '\\\\';
                nVal = match;
            }
            if (callback) {
                r = callback(match, nVal);
                if (r) nVal = r;
            }
            return nVal;
        });
    }
    MYJ.extend('escapeChar', _escapeChar);

	/*
	* 获取设置图片真实宽高的方法
	* @param $img 图片节点
	* @param call 回调函数，返回当前图片节点、宽、高到函数中
	* */
	MYJ.extend('getImgRealPX', function ($img, call){
		$img.off('load').on('load', function () {
			var $that = $(this),
				width = $that[0].naturalWidth,
				height = $that[0].naturalHeight,
                $imgSize = $that.closest('.out').find('.imgSize'),
				src = $that.attr('src'),
                isDefaultImg = src.endWith('/static/img/addImg.jpg') || src.endWith('/static/img/kong.png');//如果是默认删除的空图，则取消尺寸信息的展示

            $imgSize.text(width + ' X ' + height).attr({
					'data-size': width + ',' + height,
					'data-width': width,
					'data-height': height
				})[isDefaultImg ? 'addClass' : 'removeClass']('hide');
			if (typeof call === 'function') {
				call($that, width, height, $imgSize, true);
			}
		});
		$img.off('error').on('error', function () {
			/*if ($img.attr('src')) {
				MYJ.message.error('图片链接异常，加载失败！');
			}*/
            var $that = $(this),
                $imgSize = $that.closest('.out').find('.imgSize');
            $imgSize.text(0 + ' X ' + 0).attr({
                'data-size': 0 + ',' + 0,
                'data-width': 0,
                'data-height': 0
            });
			if (typeof call === 'function') {
				call($that, 0, 0, $imgSize, false);
			}
		});
	});
    /**
	 *	文件下载
	 *	@param option 配置
	 *	@param option.url 文件链接
	 *	@param option.name 文件名称
	 *  @param option.success 成功回调
	 *  @param option.error 失败回调
	 *
	 **/
	MYJ.extend('downloadFile', function(option){
		var xhr = new XMLHttpRequest();
		xhr.onreadystatechange = function () {
			if (xhr.readyState === 4) {
				var link = document.createElement("a");
				var _url = window.URL.createObjectURL(xhr.response);
				link.href = _url;
				link.download = option.name || 'download';
				link.click();
				window.URL.revokeObjectURL(_url);
				typeof option.success === 'function' && option.success();
			}
		};
		xhr.onerror = function () {
			typeof option.error === 'function' && option.error();
		};
		// 需要指定响应类型为 blob
		xhr.responseType = "blob";
		xhr.open("get", option.url);
		xhr.send();
	});

	/**
	 * 弹层的z-index层级属性值赋值
	 **/
	MYJ.extend('modalZindex', (function () {
		var zIndexNum = 2999;

		return function () {
			zIndexNum++;
			return zIndexNum;
		};
	})());

	/**
	 * 	通过国家站点二字码或语言二字码，获取对应的中文语言名称
	 * 	@param code 语言二字码
	 * 	@return codeZhName 语言二字码对应的中文语言名称
	 **/
	MyjCla.prototype.getLanguageZhName = function (code) {
		if (!this.languageMap) {
			this.languageMap = {
				'zh': '中文',
				'cn': '中文',
				'en': '英文',
				'en-us': '英文',
				'en-gb': '英文',
				'en-au': '英文',
				'en-sg': '英文',
				'tw': '繁体',
				'zhtw': '繁体',
				'zh_tw': '繁体',
				'zh-tw': '繁体',
				'cntw': '繁体',
				'cn-tw': '繁体',
				'cn_tw': '繁体',
				'th': '泰语',
				'vi': '越南语',
				'vn': '越南语',
				'pt': '葡萄牙语',
				'br': '葡萄牙语',
				'pt-br': '葡萄牙语',
				'id': '印尼语',
				'es': '西班牙语',
				'mx': '西班牙语',
				'co': '西班牙语',
				'cl': '西班牙语',
				'es-mx': '西班牙语',
				'es-es': '西班牙语',
				'ph': '菲律宾语',
				'fil': '菲律宾语',
				'pl': '波兰语',
				'pi-pl': '波兰语',
				'fr': '法语',
				'fr-fr': '法语',
				'fr-be': '法语',
				'ja': '日语',
				'ja-jp': '日语',
				'ko': '韩语',
				'ms': '马来语',
				'nl': '荷兰语',
				'ni-nl': '荷兰语',
				'nl-be': '荷兰语',
				'it': '意大利语',
				'it-it': '意大利语',
				'de': '德语',
				'de-de': '德语',
				'tr': '土耳其语',
				'tr-tr': '土耳其语',
				'hi': '印地语',
				'he': '希伯来语',
				'sv': '瑞典语',
				'sv-se': '瑞典语',
				'ar': '阿拉伯语',
				'ar-sa': '阿拉伯语',
				'ar-ae': '阿拉伯语',
				'ar-eg': '阿拉伯语',
				'ru': '俄语',
				// 'pk': '乌尔都语', //巴基斯坦-乌尔都语
				'ur': '乌尔都语', //巴基斯坦-乌尔都语
				// 'lk': '僧伽罗语', //斯里兰卡-僧伽罗语
				'si': '僧伽罗语', //斯里兰卡-僧伽罗语
				// 'np': '尼泊尔语', //尼泊尔-尼泊尔语
				'ne': '尼泊尔语', //尼泊尔-尼泊尔语
				// 'bd': '孟加拉语', //孟加拉-孟加拉语
				'bn': '孟加拉语', //孟加拉-孟加拉语
				'my': '缅甸语', //缅甸-缅甸语
				'auto': '源语言',
				'site': '站点语言'
			};
		}
		return this.languageMap[$.trim(code).toLowerCase()];
	};

	/**
	 *  计算要统计的字符在一个原始字符串中出现的总次数
	 *  @param str 原始字符串
	 *  @param target 要统计的字符
	 *  @return sum 返回要统计的字符在原始字符串中出现的总次数
	 **/
	MyjCla.prototype.sumOfCharInString = function (str, target) {
		var sum = 0;
		if (str && target) {
			var index = str.indexOf(target);

			while (index > -1) {
				index = str.indexOf(target, index + 1);
				sum++;
			}
		}
		return sum;
	};


	/**
	 *  根据站点名称获取币种
	 *  @param site 站点二字码
	 *  @return currency 返回站点二字码对应的币种
	 **/
	MyjCla.prototype.getCurrencyBySite = function (site) {
		if (!this.siteCurrencyData) {
			this.siteCurrencyData = {
				tw: 'TWD',
				th: 'THB',
				my: 'MYR',
				sg: 'SGD',
				vn: 'VND',
				id: 'IDR',
				ph: 'PHP',
				br: 'BRL',
				mx: 'MXN',
				co: 'COP',
				cl: 'CLP',
				pl: 'PLN',
				fr: 'EUR',
				ed: 'EUR',
				ar: 'ARS',
				gb: 'GBP',
				uk: 'GBP',
				es: 'EUR'
			};
		}
		return this.siteCurrencyData[site.toLowerCase()];
	};


	/**
	 *  公用的复制方法，此方法主要用在需要复制的内容不固定时，如果内容固定则使用copy.js里面提到的两种方式
	 *  @param copyText 要复制的内容
	 **/
	MyjCla.prototype.copyText = function (copyText) {
		//如果是空、null、undefined 则return，不能用!copyText判断，数字0会被判断为false
		if (copyText === '' || copyText === null || copyText === undefined) return;
		var $copyTextAreaBox = $('#copyTextAreaBox');
		if (!$copyTextAreaBox.length) {
			$copyTextAreaBox = $('<textarea id="copyTextAreaBox" style="position: fixed; margin-top: -99999px;"></textarea>');
			$('body').append($copyTextAreaBox);
		}
		$copyTextAreaBox.val(copyText).select();
		document.execCommand('Copy'); //执行浏览器复制命令
		//添加提示语
		$.fn.message({type: 'success', msg: '复制成功', existTime: 2000});
	};


	/**
	 *  不刷新页面替换浏览器地址，替换路径是从主域名之后开始替换
	 *  例子：目前浏览器地址是：www.dianxiaomi.com/home/index.htm；使用MYJ.winHrefHistoryReplace('home/indexNew.htm')替换;
	 *  则浏览器地址会变成www.dianxiaomi.com/home/indexNew.htm
	 *  @param url 要替换的地址
	 *  @param isGoToBack 是否支持替换地址后可以后退回到上一个地址
	 **/
	MyjCla.prototype.winHrefHistoryReplace = function (url, isGoToBack) {
		if (url) { //地址存在
			if (isGoToBack) { //如果是true
				// pushState方法是对浏览器历史记录进行更改,可以使用浏览器后退回替换前的上一个地址页面
				history.pushState({}, '', url);
			} else {
				// replaceState方法是对浏览器地址直接进行更改,无法使用浏览器后退回替换前的上一个地址页面
				history.replaceState({}, '', url);
			}
		}
	};


	/**
	 *  清除数组中内容为空的下标值
	 *  @param arr 要清除空内容的数组
	 *  @return arr 返回清除了空内容之后的数组
	 **/
	MyjCla.prototype.clearArrayEmptyItem = function (arr) {
		if (arr && arr.length) {
			var newArr = [];
			for (var i = 0; i < arr.length; i++) {
				if ($.trim(arr[i])) {
					newArr.push(arr[i]);
				}
			}
			return newArr;
		}
		return arr;
	};


	/**
	 * 绑定滚动事件
	 * @param call 滚动事件触发时执行的回调函数，执行call时会再传一个回调函数过去，调用传过去的回调函数且传了个true的话，则去除当前的滚动条绑定事件
	 * @param stoTime 延时器时间，是否需要延时器节流，如果有值则需要，根据该值多少毫秒后才执行一次
	 **/
	MyjCla.prototype.bindScrollFn = function (call, stoTime) {
		var timeoutId = null;
		window.onscroll = function () {
			if (stoTime) {
				clearTimeout(timeoutId);
				timeoutId = setTimeout(function () {
					clearTimeout(timeoutId);
					timeoutId = null;
					call(function (isClearScroll) {
						if (isClearScroll) {
							window.onscroll = null;
						}
					});
				}, stoTime);
			} else {
				call(function (isClearScroll) {
					if (isClearScroll) {
						window.onscroll = null;
					}
				});
			}
		}
	};

	/**
	 * 	数字运算 （解决 加减乘除 因二进制等问题导致精度丢失 例如：2.01*1000）
	 * 	@param num1 第1个数字
	 * 	@param num2 第2个数字
	 * 	@param type 计算类型： '+'  '-'  '*'  '/' (默认: '+')
	 * 	@param decimal 保留几位小数 （默认为直接计算结果）
	 * 	@param halfAdjust  含保留小数时是否四舍五入 （默认 true 四舍五入）
	 * 	@return 返回结果： 返回值为计算结果  类型： 1.含保留位数则为 string 类型，2.不含保留位数则为 number 型
	 **/
	MyjCla.prototype.calculationNumerical = function (num1, num2, type, decimal, halfAdjust) {
		var type = type ? type : '+',
			decimal = decimal ? +decimal : '',
			halfAdjust = halfAdjust !== undefined ? halfAdjust : true,
			num1Str = num1.toString(),
			num2Str = num2.toString(),
			num1Arr = num1Str.split('.'),
			num2Arr = num2Str.split('.'),
			r1 = num1Arr[1] ? num1Arr[1].length : 0,
			r2 = num2Arr[1] ? num2Arr[1].length : 0,
			arg1 = num1Str.replace('.', ''),
			arg2 = num2Str.replace('.', ''),
            total = 0;
		if (type === '+' || type === '-') {
			var c = Math.abs(r1 - r2),
				m = Math.pow(10, Math.max(r1, r2)),
				cm = Math.pow(10, c);
			num1 = Number(arg1);
			num2 = Number(arg2);
			if (r1 > r2) {
				num2 = Number(arg2) * cm;
			} else {
				num1 = Number(arg1) * cm;
			}
            if (type === '+') {
				total =  (num1 + num2) / m;
			} else {
				total =  (num1 - num2) / m;
			}
        }
		if (type === '*') {
			total = Number(arg1) * Number(arg2) / Math.pow(10, r1 + r2);
		}
		if (type === '/') {
			total = Number(arg1) / Number(arg2) / Math.pow(10, r1 - r2);
		}
		// 四舍五入 保留位数
		if (decimal && halfAdjust) {
			var totalArr = total.toString().split('.'),
				decimalStr = ''; // 小数部分字符串
			if(totalArr.length > 1 && totalArr[1].length > decimal) {
				decimalStr = totalArr[1].slice(decimal, decimal + 1);
				if(decimalStr === '5') {
					// 这里可能会存在 0.1 ** 5 = 0.000010000000000000003 但不影响四舍五入
                    total += Math.pow(0.1, decimal+1);
				}
			}
			total = total.toFixed(decimal);
		}
		// 不四舍五入 保留位数
		if (decimal && !halfAdjust) {
			total = formatDecimal(total, decimal);
		}
		return total;
	};

	/**
	* 全局产品刊登发布后保留原有内容发布
	* 发布后提示弹层都用id=quoteProductId隐藏域获取返回的产品id
	* @param platform 平台名称
	* */
	MyjCla.prototype.citingCurrentPlatformProduct = function (platform) {
		var url = '/' + platform + 'Product/quoteEdit.htm?id=' + $("#quoteProductId").val();

		if (platform === 'ozon') {
			url += '&singleCopy=1';
		}

		window.location.href = url;
	};


	/**
	* 正则表达式检测通用函数，常用的正则表达式条件都写到这个方法里面
	* @param {Object} option--参数配置对象
	* 	@param {String} option.str--需要检测的字符
	* 	@param {String} option.testType--需要执行什么条件的正则表达式
	* 	@param {Boolean} option.isReturnReg--是否把指定条件的正则表达式返回出去
	* 	@param {Boolean} option.isReplace--是否需要直接把str内容进行replace过滤
	* 	@param {String} option.replaceStr--需要把str内容进行replace过滤为什么值，如果不传则替换为空
	* 	@return Boolean|RegExp|String
	*  			如果没有找到对应的正则表达式判断条件则默认返回false
	* 			如果isReturnReg是true，则返回指定的正则表达式
	* 			如果isReplace是true，则返回replace之后的值
	* 			如果以上都不是，则返回正则表达式判断的结果，返回true(包含)或false(不包含)
	**/
	MyjCla.prototype.regTest = function (option) {
		var regObj = {
			// 中文汉字(\u4e00-\u9fa5)\中文符号(\u3000-\u303f)\全角字符(\ufe30-\uffa0)，返回true说明包含，false说明不包含
			zh: /[\u4e00-\u9fa5\u3000-\u303f\ufe30-\uffa0]/g,

			// 匹配空格 &#12288; &nbsp; &ensp; &emsp; &thinsp; \u00a0，返回true说明包含，false说明不包含
			nbsp: /[　     ]/g,

			// 匹配不可见特殊字符，返回true说明包含，false说明不包含
			notVisible: /[\u200B\u001d\u200e]/g,

			// 匹配图片地址是否符合要求，以http://或https://开头，且包含常见的图片格式后缀(因为有些图后面带参数了，所以不能判断后缀结尾)，返回true说明符合，false说明不符合
			// imgUrl: /^(http|https|HTTP|HTTPS):\/\/\S*\.(jpg|jpeg|png|gif|bmp|ico|pcx|tif|raw|tga)/g
			// 有些图片不会包含jpg|jpeg|png这种后缀，但是也属于正常图片，所以先不验证是否包含图片格式后缀，
			// 返回true说明符合，false说明不符合
			imgUrl: /^(http|https|HTTP|HTTPS):\/\/\S*/g
		};

		if (option && regObj[option.testType]) { //如果存在正则表达式条件
			if (option.isReturnReg) { //如果是true，则把正则表达式返回出去
				return regObj[option.testType];
			}

			if (option.isReplace) { //如果是true，则需要替换字符，并把替换后的字符结果返回出去
				return option.str ? option.str.replace(regObj[option.testType], option.replaceStr !== undefined ? option.replaceStr : '') : '';
			}

			//返回正则表达式判断结果
			return regObj[option.testType].test(option.str);
		}

		//如果不存在正则表达式条件，则直接返回false
		return false;
	};

	/**
	* 图片地址兼容处理，替换外部图片地址，有些平台图片无法访问，需要替换为其它地址才能访问
	* 	@param {Object} options--配置对象
	* 	    @param {String} options.url--需要替换的图片url
	* 	    @param {Boolean} options.reverse--是否需要反向替换（还原图片地址时用到）
	* 	    @param {Boolean} options.enCode--是否需要给url转码，防止xss攻击用，不传或false都是默认转码，true的话不转码
	* 	    @param {Boolean} options.isDesc--是否是把整段描述内容丢进来了，如果是true则是，那么就不给内容前面添加图片前缀地址
	* 	@return String url--替换后的图片url
	**/
	MyjCla.prototype.getImgReplaceUrl = function (options) {
		var imgReplaceUrlObj = {
			'cdn.shopify.com': 'cdn.shopifycdn.net',
			'm.media-amazon.com': 'images-na.ssl-images-amazon.com',
			'my-test-11.slatic.net': 'my-live.slatic.net',
			// 'img.joomcdn.net': 'cdnjoom.dianxiaomi.com',
			'https://img.kwcdn.com': 'https://kj-img.pddpic.com',
			'www.etsy.com': 'i.etsystatic.com',
			'cf.shopee.com.my': 's-cf-tw.shopeesz.com',
			'ae01.alicdn.com': 'ae02.alicdn.com'
			// 'i.ebayimg.com': 'cdn-platform.dianxiaomi.com/ebayimg'
		};
		var getImgReplaceUrlFn = function (option) {
			var url = option.url,
				reverse = option.reverse,
				enCode = option.enCode,
				isDesc = option.isDesc;
			if (url) {
				//如果isDesc是true，则当前是把整段描述内容丢进来了，这种情况不能在前面添加图片前缀地址
				if(!isDesc && url.indexOf('http') === -1 && url.indexOf('HTTP') === -1){
					url = getPicRealUrl(url);
				}
				//要替换的地址
				$.each(imgReplaceUrlObj, function (i, j) {
					if (!reverse && url.indexOf(i) !== -1) {
						url = returnStringReplaceResult(url, i, j, true);
						//不结束循环，可能传的是富文本描述的整个描述内容，可能会需要替换多个不同域名的图片url
						// return false;
					} else if (reverse && url.indexOf(j) !== -1) {
						url = returnStringReplaceResult(url, j, i, true);
                        //不结束循环，可能传的是富文本描述的整个描述内容，可能会需要替换多个不同域名的图片url
                        // return false;
					}
				});
				//如果没传或者是false，则需要转码，如果传了true则不转码
				if (!enCode) {
                    try {
                        //加个捕获，decodeURI可能会报错
                        if (reverse) { //如果reverse是true则当前是保存，需要解码url提交给后端
                            url = decodeURI(url); //图片url解码，在保存给后端的时候
                        } else { //如果reverse是false则当前是生成展示，需要转码url避免xss攻击
							try {
								//加个捕获，decodeURI可能会报错
								var newUrl = decodeURI(url); //图片url解码
								//如果解码后的newUrl调用regTest方法返回true，则说明当前图片地址可能是被加密过的带中文内容的图片地址，等下面的数组push时再重新加密一下就好了
								//如果返回的是false，则说明当前图片地址不是带中文内容的图片地址，则需要再次判断解码后的图片地址是否等于原图，如果不等于，则需要重新加密还原回去，然后在下面的数组push时再加密一次
								if (!MYJ.regTest({str: newUrl, testType: 'zh'}) && newUrl !== $.trim(url)) {
									url = encodeURI(newUrl);
								} else {
									url = newUrl;
								}
							} catch (e) {}
                            url = encodeURI(url); //图片url加密，解决图片url的xss攻击问题
                        }
                    } catch (e) {}
                }
			}
			return url;
		};
		MyjCla.prototype.getImgReplaceUrl = getImgReplaceUrlFn;
		return getImgReplaceUrlFn(options);
	};

	/**
	 * 	新版二次确认提示弹层
	 * 	@param {Object} optionObj--弹层配置对象
	 * 		@param {String} optionObj.type--弹层类型：info=提示类弹层；error=错误类弹层；success=成功类弹层；warning=警告类弹层；delete=删除类弹层
	 * 		@param {String} optionObj.width--弹层宽度，默认0，0不会赋值弹层宽，则会使用弹层默认宽度600
	 * 		@param {String} optionObj.title--弹层标题，默认“提示”
	 * 		@param {Boolean} optionObj.typeHead--是否不展示头部标题，true为不展示，不传或false默认展示
	 * 		@param {String} optionObj.content--弹层内容，默认为空
	 * 		@param {Boolean} optionObj.isText--弹层内容是否以text纯文本内容方式生成，默认false
	 * 		@param {String} optionObj.enter--弹层确认按钮文案，默认“确定”
	 * 		@param {String} optionObj.cancel--弹层取消按钮文案，默认“取消”
	 * 		@param {String} optionObj.enterClass--弹层确认按钮class类 默认不传则="button btn-determine"
	 * 		@param {String} optionObj.cancelClass--弹层取消按钮class类  默认不传则="button btn-gray"
	 * 		@param {Function} optionObj.callback--弹层确认取消的回调函数，会传一个布尔值回去，true=点击了确认，false=点击了取消
	 **/
	MyjCla.prototype.confirm = function (optionObj) {
		var defaultOpt = {
				type: 'info', //弹层类型，默认提示类
				width: 500, //弹层宽度，默认500
				title: '提示', //弹层标题
				typeHead: false, //是否不展示头部标题，true为不展示，不传或false默认展示
				content: '', //弹层内容
				isText: false, //弹层内容是否以text纯文本内容方式生成
				enter: '确定', //弹层确认按钮文案
				cancel: '取消', //弹层取消按钮文案
				enterClass: 'button btn-determine', //弹层确认按钮class类 默认不传则="button btn-determine"
				cancelClass: 'button btn-gray', //弹层取消按钮class类  默认不传则="button btn-gray"
				hideEnter: false, //是否隐藏弹层确认按钮
				hideCancel: false, //是否隐藏弹层取消按钮
				callback: null //弹层确认\取消的回调函数
			},
			$modal = $('<div class="modal in-modal" id="myjCommConfirmModal" tabindex="-1" role="dialog" aria-hidden="false" data-backdrop="static" data-keyboard="false">' +
				'<div class="modal-dialog" id="myjCommConfirmDialog">' +
				'	<div class="modal-content">' +
				'		<div class="modal-header"><button type="button" class="close" data-type="0" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button></div>' +
				'		<div class="modal-body p-top0 p-left24">' +
				'			<div class="flex h18 lh18 f0">' +
				'				<i class="myj-comm-confirm-icon" id="myjCommConfirmIcon"></i>' +
				'				<span class="f16 f-w600" id="myjCommConfirmTitle"></span></div>' +
				'			<div class="myj-comm-confirm-content" id="myjCommConfirmContent"></div>' +
				'		</div>' +
				'		<div class="modal-footer">' +
				'			<button type="button" class="button btn-determine" id="myjCommConfirmEnterBtn" data-type="1" data-dismiss="modal"></button>' +
				'			<button type="button" class="button btn-gray m-left10" id="myjCommConfirmCancelBtn" data-type="0" data-dismiss="modal"></button>' +
				'		</div></div></div></div>'),
			$myjCommConfirmDialog = $modal.find('#myjCommConfirmDialog'), //弹层外层，设置弹层宽度用
			$myjCommConfirmIcon = $modal.find('#myjCommConfirmIcon'), //弹层的icon节点，根据不同type修改class类展示对应icon
			$myjCommConfirmTitle = $modal.find('#myjCommConfirmTitle'), //弹层的icon边上的标题节点，展示主信息
			$myjCommConfirmContent = $modal.find('#myjCommConfirmContent'), //弹层的详细内容节点，展示详细说明内容
			$myjCommConfirmEnterBtn = $modal.find('#myjCommConfirmEnterBtn'), //弹层的确认按钮节点，更换按钮样式和文案用
			$myjCommConfirmCancelBtn = $modal.find('#myjCommConfirmCancelBtn'), //弹层的取消按钮节点
			$modalBtn = $modal.find('[data-dismiss="modal"]'); //弹层的右上角的x按钮，下面的确认和取消按钮，用来注册点击事件调用回调方法

		//根据type获取icon class类
		var getIconClass = function (type) {
			var iconClass = 'myj-comm-confirm-icon iconfont'; //icon默认class
			switch (type) {
				case 'error': //如果是错误类
					iconClass += ' icon_modal_error';
					break;
				case 'success': //如果是成功类
					iconClass += ' icon_modal_success';
					break;
				case 'warning': //如果是警告类
				case 'delete': //如果是删除类，警告和删除用同一个icon
					iconClass += ' icon_modal_warning';
					break;
				default: //其它的都属于提示类
					iconClass += ' icon_modal_info';
					break;
			}
			return iconClass;
		};

		//显示弹层
		var showConfirmModal = function (optionObj) {
			var newOptionObj = $.extend({}, defaultOpt, optionObj);

			//判断是否需要自定义弹层宽度
			if (newOptionObj.width) {
				var width = newOptionObj.width;
				if (String(width).indexOf('px') === -1) {
					width = width + 'px';
				}
				$myjCommConfirmDialog.css('width', width);
			}

			//是否隐藏确认按钮
			if (newOptionObj.hideEnter) {
                $myjCommConfirmEnterBtn.hide();
            } else {
                $myjCommConfirmEnterBtn.show();
            }
            //是否隐藏取消按钮
            if (newOptionObj.hideCancel) {
                $myjCommConfirmCancelBtn.hide();
            } else {
                $myjCommConfirmCancelBtn.show();
            }
            //更新确认按钮的class
			$myjCommConfirmEnterBtn.removeClass().addClass(newOptionObj.enterClass);
			//更新取消按钮的class
			$myjCommConfirmCancelBtn.removeClass().addClass(newOptionObj.cancelClass + ' m-left10');

			//更换icon类
			$myjCommConfirmIcon.removeClass().addClass(getIconClass(newOptionObj.type));
			//赋值标题主提示内容
			$myjCommConfirmTitle[newOptionObj.isText ? 'text' : 'html'](newOptionObj.title);
			//赋值详情说明内容
			$myjCommConfirmContent[newOptionObj.isText ? 'text' : 'html'](newOptionObj.content);
			//赋值确认按钮文案
			$myjCommConfirmEnterBtn.text(newOptionObj.enter);
			//赋值取消按钮文案
			$myjCommConfirmCancelBtn.text(newOptionObj.cancel);
			//如果是删除类弹层
			if (newOptionObj.type === 'delete') {
				//需要把确认按钮的样式替换为红色删除类样式
				$myjCommConfirmEnterBtn.text(optionObj.enter ? optionObj.enter : '删除').removeClass('btn-determine').addClass('btn-delete');
			} else { //如果不是删除类弹层，则默认使用蓝色提示信息样式
				$myjCommConfirmEnterBtn.removeClass().addClass(newOptionObj.enterClass);
			}
			//绑定按钮点击事件
			$modalBtn.off('click').on('click', function () {
				//如果有传回调函数，则调用回调
				if (typeof newOptionObj.callback === 'function') {
					//如果data-type=1则是点击了确认，如果是0则是取消
					newOptionObj.callback($(this).attr('data-type') === '1');
				}
				//关闭弹层
				$modal.modal('hide');
			});
			//显示弹层
			$modal.modal('show');
		};
		$('body').append($modal); //把弹层添加到页面上
		//调用方法
		showConfirmModal(optionObj);

		//把方法重新替换，下次进入则不需要重新声明默认配置项和弹层节点了
		MyjCla.prototype.confirm = showConfirmModal;
	};

	MyjCla.prototype.navTab = {
		/**
		 * 选中头部tab一级导航栏
		 * @param id tab栏的id名
		 * @return void
		 */
		select: function(id){
			var $tabWareHose = $('#' + id);
			$tabWareHose.closest('#headTab').find('li').removeClass('li-active');
			$tabWareHose.addClass('li-active');
		}
	};

	/**
	 * 	方法描述内容   判断是否开通VIP
	 * 	@param showError 是否展示小条提示 默认false不展示
	 * 	@param errorMsg 小条提示文字内容
	 * 	@return call 回调参数（isVip, vipLeval）
	 * 		isVip: true是vip false不是vip
	 * 		vipLeval: vip 等级
	 **/
	MyjCla.prototype.verifyVipFn = function (showError, errorMsg, call) {
		var vipLeval = +$('#userVIPLeVel').val(),
			isNotVip = vipLeval < 1,
			msg = !!errorMsg ? errorMsg : '此功能为VIP专属，';

		if (isNotVip && !!showError) {
			$.fn.message({type:'error', msg: msg + '使用此功能需<a href="' + locHref + 'user/vipInfo.htm" target="_blank">升级VIP</a>'});
		}

		call && typeof call === 'function' && call(!isNotVip, vipLeval);

	};

	/**
	 * 	验证来源URL，是否为空，或者是否超长2000字符，如果是，则返回报错信息
	 * 	@param sourceUrls 来源URL字符串内容，所有来源URL字符串内容拼接
	 * 	@param isVerifyEmpty 是否需要验证不能为空才行
	 **/
	MyjCla.prototype.verifySourceUrlsFn = function (sourceUrls, isVerifyEmpty) {
		if (!sourceUrls) sourceUrls = '';
		sourceUrls = $.trim(sourceUrls);
		if (isVerifyEmpty && !sourceUrls) {
			MYJ.message.error('来源url不能为空');
			return true;
		} else if (sourceUrls.length > 2000) {
			MYJ.message.error('来源url长度不能超过2000字符');
			return true;
		} else {
			return false;
		}
	};


	/**
	* 产品模块的导出图片方法，注意：使用该方法需要引用jszip.min.js和FileSaver.js
	* @param {String} platformName 平台名称，需要传展示给用户看的平台名称，比如:Wish(英文的平台名，记得大小写)、速卖通(中文的平台名不要传英文，比如smt)
	* @param {String} dxmState 当前产品的编辑页状态，是采集箱(draft)、还是待发布(offline)、还是在线(online)
	* @param {jQuery} $img 当前需要导出的图片节点
	* @param {Boolean} isEditor 是否是富文本编辑器里面的导出全部图片
	**/
	MyjCla.prototype.imageDownload = function (platformName, dxmState, $img, isEditor) {
		var canvas = document.createElement('canvas'), //创建一个虚拟canvas节点
			ctx = canvas.getContext('2d');

		//前端导出图片进度条弹层显示逻辑
		var webExportImgFnModal = function (totalNum, countNum, isSuccess) {
			var $commonProgressBarModal = $('#commonProgressBarModal'),
				$commonProgressBarBox = $('#commonProgressBarBox'),
				$commonProgressBarStatus = $('#commonProgressBarStatus'),
				$commonCosUpDownloadBox = $('#commonCosUpDownloadBox'),
				$commonCosReportShow = $('#commonCosReportShow'),
				$commonProgressBarDetail = $('#commonProgressBarDetail'),
				$downloadFill = $commonProgressBarModal.find('.downloadFill'),
				$commonExportShowBox = $commonProgressBarModal.find('.commonExportShowBox'),
				$commonNotExportShowBox = $commonProgressBarModal.find('.commonNotExportShowBox'),
				$commonExportNum = $commonProgressBarModal.find('#commonExportNum'),
				$commonExportUnit = $commonProgressBarModal.find('#commonExportUnit'),
				$commonPromptStripTop = $commonProgressBarModal.find('.commonPromptStripTop'),
				$commonNoticeFooter = $commonProgressBarModal.find('#commonNoticeFooterId'), //提示说明
				stoId = null,
				num = 0;

			//初始化进度条弹层信息
			var initModalMsg = function () {
				$commonExportNum.text('0');
				$commonNotExportShowBox.addClass('hide');
				$commonExportShowBox.removeClass('hide');
				$commonPromptStripTop.hide().find('.commonPromptStripCon').empty();
				$commonProgressBarStatus.text('正在导出中，请稍候...').removeClass('f-red hide'); //状态文案初始化为进行中
				$commonProgressBarDetail.empty(); //详情内容清空

				$commonCosUpDownloadBox.empty(); // 多个下载文件按钮清空
				$commonCosReportShow.empty(); // 拆分文件个数文案清空
				$commonNoticeFooter.empty(); //清空提示文案
				$downloadFill.addClass('hide'); // 隐藏弹窗底部下载按钮

				$commonExportUnit.text(' 张'); // 导出的数量单位设置，默认'张'
				$('.commonProgressBarModalTitle').text('导出图片'); //进度条弹层标题
				$commonProgressBarBox.css({'display': 'none', 'width': '0%'}); //把进度条隐藏后归零
				var sto = setTimeout(function () {
					clearTimeout(sto);
					sto = null;
					$commonProgressBarBox.css('display', ''); //10毫秒后把进度条显示，防止用户看到进度条倒退回百分之0的状态
				}, 1);
				$commonProgressBarModal.modal('show'); //显示进度条弹层
			};

			//进度条进度计算方法
			var progressBarWidthComputeFn = function (totalNum, countNum, isSuccess) {
				//这里num是在计算进度条的进度
				var status = '正在导出中，请稍候...';

				//只有countNum=1的时候进入，countNum=1相当于是第一张图加载完成
				if (countNum === 1) {
					initModalMsg(); //调用初始化进度条弹层方法
					var count = 0;
					//设置定时器，每1.5秒执行一次，改变进度条进度
					stoId = setInterval(function () {
						count++; //计数+1
						//只有计数小于总数才进入
						if (count < totalNum) {
							$commonExportNum.text(count);
							num = Math.round(totalNum ? (count / totalNum * 100) : (count % 100));
							$commonProgressBarBox.css('width', num + '%');
						} else {
							clearInterval(stoId);
							stoId = null;
						}
					}, 1500);
				}

				//如果总数和计数相等，且isSuccess是true，则进入if
				if(totalNum === countNum && isSuccess){
					status = '导出成功！您的文件已自动下载';
					clearInterval(stoId);
					stoId = null;
					$commonExportNum.text(countNum);
					$commonProgressBarBox.css('width', '100%').removeClass('active'); //把进度条设为百分之100
				}
				$commonProgressBarStatus.html(status); //状态
			};
			//调用进度计算方法
			progressBarWidthComputeFn(totalNum, countNum, isSuccess);
			//把进度计算方法覆盖掉webExportImgFnModal方法，就不需要每次进来都重新获取一下进度条弹层节点了
			webExportImgFnModal = progressBarWidthComputeFn;
		};

		//前端图片导出方法
		var webExportZipFn = function (newZip, fileName, imgTotalLen, successLen) {
			//调用zip的方法把存到fileZip.file()里面的图片数据打包成zip文件流
			newZip.generateAsync({
				type: 'blob',// 压缩类型
				compression: 'DEFLATE', // STORE=默认不压缩 DEFLATE=需要压缩
				compressionOptions: {
					level: 9 // 压缩等级1~9 1压缩速度最快，9最优压缩方式
				}
			}).then(function(content) {
				//调用FileSaver.js里面的saveAs方法，把返回的content zip文件流转换为下载链接，然后自动下载
				saveAs(content, fileName + '.zip');
				//调用进度条进度计算方法，把进度条进度设为100%
				webExportImgFnModal(imgTotalLen, successLen, true);
			});
		};

		//后端图片导出方法
		var javaExportZipFn = function (imgLength, urls, fileName, uniqueKey) {
			//先隐藏进度条弹层
			$('#commonProgressBarModal').modal('hide');
			//调用一下进度条计算方法，把定时器结束掉
			webExportImgFnModal(imgLength, imgLength, true);

			//调用后端接口，走后端导出
			commonProgressBarModalShow({
				title: '导出图片',
				ajaxUrl: 'album/batchDownloadFromProduct.json',
				ajaxData: {
					urls: urls,
					fileName: fileName,
					uniqueKey: uniqueKey
				},
				hideDetail: true, //是否隐藏进度条弹层的详情结果信息
				isDownLoad: true, //是否是下载进度条弹层
				statusText: '正在导出中，请稍候...',
				successText: '导出成功！您的文件已自动下载，如果文件没有自动下载，请在5分钟内点击【下载】下载图片文件',
				callback: function (result, $commonProgressBarModal) {
					//后端接口导出完成后，直接打开下载链接自动下载
					window.open($commonProgressBarModal.find('.highSpeedDownload').find('a').attr('href'));
				}
			});
		};

		//产品模块的导出图片方法
		var imageDownloadFn = function (platformName, dxmState, $img, isEditor) {
			var urls = '',
				fileName = platformName || '',
				uniqueKey = fileName,
				productId = $('#productId').val(),
				newZip = '', //创建zip对象
				fileZip = '', //获取filezip对象，用来存图片文件
				imgTotalLen = 0, //图片总数
				successLen = 0, //图片加载成功数
				errorLen = 0, //图片加载失败数
				//获取当前时间，比如当前时间是2024-01-02 16:35:20，则获取到：20240102163520
				dateStr = new Date().format('yyyyMMddhhmmss');

			try {
			    //加个异常捕获，如果没有引入jsZip的文件，则这里new JSZip会报错
				newZip = new JSZip(); //创建zip对象
				fileZip = newZip.folder(); //获取filezip对象，用来存图片文件
			} catch (e) {

			}
			//前端导出-图片加载函数，先确认图片是否能在店小秘页面加载成功，如果全部能加载则走前端导出，如果加载失败则说明有图片跨域，无法前端导出
			var imgLoadingFn = function (index, url) {
				var img = new Image();
				img.setAttribute('crossOrigin', 'anonymous'); //解决图片跨域导致canvas无法将该图片渲染到画布问题
				img.onload = function () {
					//只有图片都没有失败的情况下，才走前端导出，如果errorLen有值，则说明有图片加载失败了，则不需要再走前端导出的逻辑了
					if (!errorLen) {
						successLen++; //成功数量+1
						//调用进度条计算方法，更新进度条
						webExportImgFnModal(imgTotalLen, successLen);
						try {
							//获取图片宽高并赋值给canvas
							canvas.width = img.width;
							canvas.height = img.height;
							//在canvas上绘制图片
							ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

							//获取图片url，获取到的是base64文件流
							var urlName = (index + 1) + '_' + url.substring(url.lastIndexOf('/') + 1), //获取图片文件名称:下标+文件名称，前面加下标是为了让用户导出的图片顺序和页面看到的顺序是一致的
								imgType = 'jpeg';

							//如果文件名称后面有'?'，则需要把'?'及后面的参数都去掉
							if (urlName.indexOf('?') !== -1) {
								urlName = urlName.substring(0, urlName.indexOf('?'));
							}

							//如果文件名称没有'.'，则说明当前文件名称没有图片后缀格式，需要拼接上格式
							if (urlName.indexOf('.') === -1){
								urlName = urlName + '.jpg';
							}
							//webp网页格式的图片转成jpg格式，兼容wind7系统的电脑显示不了的问题
							if ((urlName).toLowerCase().indexOf('.webp') !== -1) {
								urlName = returnStringReplaceResult(urlName, '.webp', '.jpg', true);
							}
							if (urlName.indexOf('.png') !== -1) {
								imgType = 'png';
							}
							//获取图片url，获取到的是base64文件流
							var base64s = canvas.toDataURL('image/' + imgType).split(',')[1];
							//把图片存到zip里面,zip.file(文件名, base64流数据, 配置对象)
							fileZip.file(urlName, base64s, {base64: true}); //需要配置base64:true
						} catch (e) {
							console.error('前端导出失败，canvas绘图报错', e);
							errorLen++; //失败数量+1
							//如果是第一次失败，直接调用后端导出
							if (errorLen === 1) {
								javaExportZipFn(imgTotalLen, urls, fileName, uniqueKey);
							}
						}
						//如果当前成功数量等于图片总数量
						if (successLen === imgTotalLen) {
							webExportZipFn(newZip, fileName, imgTotalLen, successLen); //调用前端导出方法进行导出
						}
					}
				};
				img.onerror = function () {
					errorLen++; //失败数量+1
					//如果是第一次失败，直接调用后端导出
					if (errorLen === 1) {
						javaExportZipFn(imgTotalLen, urls, fileName, uniqueKey);
					}
				};
				img.src = getPicRealUrl(url);
			};

			if (isEditor) { //如果是富文本编辑器的导出图片
				fileName += dateStr + '_';
				urls = $img; //此时的$img直接就是图片的url链接集合了
				uniqueKey = dxmState; //此时的dxmState是需要拼接到导出文件名称里面的后缀值
				if (urls) {
				    //只有saveAs方法存在，才走前端图片导出
					if (typeof saveAs === 'function') {
						var urlArr = urls.split(',');
						imgTotalLen = urlArr.length;
						$.each(urlArr, function (i, j) {
							imgLoadingFn(i, j);
						});
					} else { //如果saveAs方法不存在则走后端接口导出
						javaExportZipFn(imgTotalLen, urls, fileName, uniqueKey);
					}
				}
			} else {
				if($.trim(dxmState) === 'crawl'){
					fileName += '_编辑_' + dateStr + '_';
					uniqueKey += 'Crawl' + productId;
				}else if($.trim(dxmState) === 'draft'){
					fileName += '_采集箱_编辑_' + dateStr + '_';
					uniqueKey += 'Draft' + productId;
				}else{
					if($.trim(dxmState) === "online"){
						fileName += '_在线产品_编辑_' + dateStr + '_';
						uniqueKey += 'Online' + productId;
					}else {
						if($.trim(dxmState) === "offline"){
							fileName += '_待发布_编辑_' + dateStr + '_';
							uniqueKey += 'WaitPublish' + productId;
						}else{
							fileName += '_创建产品_' + dateStr + '_';
							uniqueKey += 'CreateProduct' + $('#sessionUserId').val();
						}
					}
				}

				imgTotalLen = $img.length;
				$.each($img, function(i, j){
					var urlDraft = $(j).attr('src');

					if (urlDraft){
						if (urlDraft.indexOf('?') !== -1 && urlDraft.indexOf('wxalbum-10001658') === -1) {
							urlDraft = urlDraft.substring(0, urlDraft.indexOf('?'));
						}
						//如果是添加图片的占位图片地址，则不导出
						if(urlDraft.indexOf('static/img/addImg.jpg') !== -1){
							imgTotalLen--;
							return;
						}
						urls += (!urls ? '' : ',') + urlDraft;
                        //只有saveAs方法存在，才走前端图片导出
                        if (typeof saveAs === 'function') {
							imgLoadingFn(i, urlDraft);
						}
					}
				});
                //如果saveAs方法不存在则走后端接口导出
                if (typeof saveAs !== 'function') {
					javaExportZipFn(imgTotalLen, urls, fileName, uniqueKey);
				}
			}

			if (!urls){
				MYJ.message.error('暂无可导出的图片');
			}
		};

		imageDownloadFn(platformName, dxmState, $img, isEditor);
		MyjCla.prototype.imageDownload = imageDownloadFn;
	};


    /**
     * 	锚点跳转事件
     * 	@param $dom 锚点定位跳转节点
     * 	@param $anchorLoCationDom 锚点位置节点，通过$dom点击时，跳转到当前对应data-name的节点位置
     * 	@param $scrollDom 计算锚点滚动距离的滚动监听节点
     **/
    MyjCla.prototype.anchorFn = function ($dom, $anchorLoCationDom, $scrollDom) {
		if (!$dom || !$dom.length) {
			$dom = $('.anchorClickBox');
		}
		if (!$anchorLoCationDom || !$anchorLoCationDom.length) {
			$anchorLoCationDom = $('.anchorLocationBox');
		}
		if (!$scrollDom || !$scrollDom.length) {
			$scrollDom = $(document);
		}
		$dom.off('click').on('click', function () {
			$anchorLoCationDom.filter('[data-name="' + $(this).attr('data-name') + '"]').scrollIntoView();
			isNotScrollFlag = true; // 把状态标为true，锚点滚动事件监听那里需要禁止执行逻辑
			var sto = setTimeout(function () {
				isNotScrollFlag = false; // 把状态标为false，锚点滚动事件监听那里允许执行逻辑
			}, 200);
			$dom.removeClass('anchor-active');
			$(this).addClass('anchor-active');
		});

		var scrollStoId = null,
			isNotScrollFlag = false;

		// 授权平台滚动事件，联动选中tab标签锚点
		var authPlatformAnchorScrollFn = function () {
			//如果延时器还没调用，或者isNotScrollFlag是true，则直接结束
			if (scrollStoId || isNotScrollFlag) {
				//如果是isNotScrollFlag是true，则改为false
				if (isNotScrollFlag) isNotScrollFlag = false;
				return;
			}
			//延时200毫秒后执行
			scrollStoId = setTimeout(function () {
				clearTimeout(scrollStoId);
				scrollStoId = null;
				//循环当前需要定位到指定位置的锚点节点
				$anchorLoCationDom.filter(':visible').each(function (i, j) {
					var thatTop = $(j).offset().top - 1;
					if (thatTop + $(j).height() > $scrollDom.scrollTop()) {
						$dom.removeClass('anchor-active');
						$dom.filter('[data-name="' + $(j).attr('data-name') + '"]').addClass('anchor-active');
						return false;
					}
				});
			}, 200);
		};
		$scrollDom.off('scroll').on('scroll', authPlatformAnchorScrollFn);
	};

	//MYJ全局方法规范示例：复制以下格式来写方法，方法注释严格按照下面这种方式写，参数用@param，返回值用@return来注释说明
	/**
	 * 	方法描述内容   第一行写方法描述内容
	 * 	@param a 参数描述内容  注意格式：@param|空格|参数名|空格|参数描述内容
     * 	@param b 参数描述内容
	 * 	@param c 参数描述内容
	 * 	@return d 返回值描述内容，没有返回值则不需要这行注释说明   注意格式：@return|空格|返回值名称|空格|返回值描述内容
	 **/
	/*MyjCla.prototype.xxx = function (a, b, c) {
		var d = a + b + c;
		return d;
	};*/
})(jQuery);

/**
 * jQuery扩展
 *
 **/
jQuery.fn.extend({
	/**
	* scrollIntoView 页面滚动条滚动到当前节点，锚点定位
	**/
	'scrollIntoView': function() {
		var _this = this;
		_this[0].scrollIntoView();
		return _this;
	},

	/**
	 * 表格固定表头\列
	 * @param {Object} optionObj--配置对象
	 *     @param {Boolean} optionObj.top--是否开启表头固定
	 *     @param {Boolean} optionObj.left--是否开启左侧列固定，如果传true，需要给需要固定左侧列的th\td节点添加上class="fixedLeftBox"
	 *     @param {Boolean} optionObj.right--是否开启右侧列固定，如果传true，需要给需要固定右侧列的th\td节点添加上class="fixedRightBox"
	 *     @param {Number} optionObj.scrollWidth--滚动条的宽度，如果不传则默认8
	 *     @param {String} optionObj.emptyDataMsg--表格没有数据时的暂无数据展示文案，不传默认“暂无数据”，可以传字符串节点进来
	 *     @param {Function} optionObj.callBack--注册完表格固定列后的回调函数
	**/
	'fixedTable': function (optionObj) {
		var $this = this,
			locHref = gitWinLocHref();

		/**
		 * 滚动事件，处理固定列的位置定位
		 * @param $that--当前注册表格固定列的外层节点
		 * @param fixedTableDomObj--当前注册表格固定列的表格dom对象集合，不用每次滚动都去页面找节点，节省性能
		**/
		var scrollFn = function ($that, fixedTableDomObj) {
			var scrollTop = $that.scrollTop(), //获取当前节点的竖向滚动条已滚动的距离
				scrollLeft = $that.scrollLeft(); //获取当前节点的横向滚动条已滚动的距离

			//如果开启表头固定
			if (optionObj.top) {
				//给thead设置top定位值，实现表头固定
				fixedTableDomObj.$fixedTableThead.css('top', scrollTop + 'px');
			}
			//如果开启左侧列固定
			if (optionObj.left) {
				//给左侧列节点设置left定位值，实现左侧列固定
				fixedTableDomObj.$fixedLeftBox.css('left', scrollLeft + 'px');
				//如果left定位值不为0
				if (scrollLeft) {
					//需要给表头和表格的每一行tr中最后一个左侧固定列节点添加一个阴影效果的class
					fixedTableDomObj.$theadLastFixedLeftBox.addClass('fixed-left-last');
					fixedTableDomObj.$tbodyLastFixedLeftBox.addClass('fixed-left-last');
				} else { //如果left定位值为0
					//需要把表头和表格的每一行tr中最后一个左侧固定列节点添加的阴影效果的class移除
					fixedTableDomObj.$theadLastFixedLeftBox.removeClass('fixed-left-last');
					fixedTableDomObj.$tbodyLastFixedLeftBox.removeClass('fixed-left-last');
				}
			}
			//如果开启右侧列固定
			if (optionObj.right) {
				var width = $that.width(), //获取当前节点的宽度
					maxHeight = $that.css('max-height'), //获取当前节点的最大高度，默认样式里面设置的是450
					tableW = fixedTableDomObj.$fixedTable.width(), //获取当前节点下的table的宽度
					height = fixedTableDomObj.$fixedTable.height(), //获取当前节点下的table的高度
					scrollW = optionObj.scrollWidth || 8, //滚动条宽度，有值以传进来的为主，没传则默认8，注册插件时默认添加了scroll-bar的class，这个类的滚动条宽默认是8
					right = tableW - width - scrollLeft - 1; //表格宽-当前节点宽-当前节点的横向滚动条滚动距离值-1(这个1代表border边框，需要-1防止右侧有1px空隙，造成滚动时右侧能看到其它非固定列的内容)

				//如果高度和最大高度都有值
				if (height && maxHeight) {
					//最大高度带有px，需要截取后获取0下标的值
					maxHeight = maxHeight.split('px')[0];
					//判断如果table的高度大于了当前节点的最大高度，这时才会有竖向滚动条
					if (height >= +maxHeight) {
						right += scrollW; //加上滚动条的宽度
					}
				}
                //有些浏览器可以不停往后拉，判断如果小于-3，则认为是拉大最后面了，直接把right赋为0
				if (right < -3) {
                    right = 0;
                }
				//给右侧列节点设置right定位值，实现右侧列固定
				fixedTableDomObj.$fixedRightBox.css('right', right + 'px');
				//如果right定位值大于2
				if (right > 2) {
					//需要给表头和表格的每一行tr中第一个右侧固定列节点添加一个阴影效果的class
					fixedTableDomObj.$theadFirstFixedRightBox.addClass('fixed-right-last');
					fixedTableDomObj.$tbodyFirstFixedRightBox.addClass('fixed-right-last');
				} else { //如果right定位值小于2
					//需要把表头和表格的每一行tr中第一个右侧固定列节点添加的阴影效果的class移除
					fixedTableDomObj.$theadFirstFixedRightBox.removeClass('fixed-right-last');
					fixedTableDomObj.$tbodyFirstFixedRightBox.removeClass('fixed-right-last');
				}
			}

			//如果有开启左侧或右侧固定列
			if (optionObj.left || optionObj.right) {
				var $checkNumCon = $that.find('.check-num-con'); //列表的已选中多少条的小黄条节点

				if ($checkNumCon.length) { //如果已选中多少条的小黄条节点存在
					//那么小黄条节点下的已选中多少条的文案节点，需要跟随固定列进行偏移
					$checkNumCon.find('.initialize').css({
						'position': 'relative',
						'left': scrollLeft
					});
				}

				var $noDataTrBox = $that.find('.noDataTrBox'), //列表的暂无数据tr节点
					$fixedTableEmpty = $that.find('.fixedTableEmpty'); //列表的固定列暂无数据节点

				//如果当前表格存在暂无数据的tr节点
				if ($noDataTrBox.length) {
					//如果当前固定列的暂无数据节点不存在
					if (!$fixedTableEmpty.length) {
						//生成固定列的暂无数据节点
						$that.append('<div class="no-data-box fixed-table-empty fixedTableEmpty">' +
							'<img src="' + locHref + 'static/img/noData.png">' +
							'<div class="p-top10">' + (optionObj.emptyDataMsg ? optionObj.emptyDataMsg : '暂无数据') + '</div></div>');
						$fixedTableEmpty = $that.find('.fixedTableEmpty');
					}
					//给固定列的暂无数据节点设置left值，跟着固定列偏移
					$fixedTableEmpty.css({'left': scrollLeft});
				}
			}
		};

		$.each($this, function (i, j) {
			var $that = $(j),
				fixedTableDomObj = {
					$fixedLeftBox: $that.find('.fixedLeftBox'), //获取当前节点下的所有左侧固定列节点
					$theadLastFixedLeftBox: $that.find('thead:first tr').find('.fixedLeftBox:last'), //获取当前节点下的每行tr中的最后一个左侧固定列节点
					$tbodyLastFixedLeftBox: $that.find('tbody:first tr').find('.fixedLeftBox:last'), //获取当前节点下的每行tr中的最后一个左侧固定列节点
					$fixedRightBox: $that.find('.fixedRightBox'), //获取当前节点下的所有右侧固定列节点
					$theadFirstFixedRightBox: $that.find('thead:first tr').find('.fixedRightBox:first'), //获取当前节点下的每行tr中的第一个右侧固定列节点
					$tbodyFirstFixedRightBox: $that.find('tbody:first tr').find('.fixedRightBox:first') //获取当前节点下的每行tr中的第一个右侧固定列节点
				};

			//给当前节点添加固定列样式类，设置scroll-bar滚动条样式
			$that.addClass('fixed-table-box scroll-bar')
				.find('table:first').addClass('fixed-table fixedTable'); //给当前节点下的表格设置固定列样式类
			fixedTableDomObj.$fixedTable = $that.find('.fixedTable'); //获取当前节点下的table表格节点

			//如果开启了表头固定
			if (optionObj.top) {
				//给当前节点下的thead节点添加固定列样式类
				$that.find('thead:first').addClass('fixed-table-thead fixedTableThead');
				fixedTableDomObj.$fixedTableThead = $that.find('.fixedTableThead'); //获取当前节点下的thead表头节点
			}
			//如果开启了左侧固定列
			if (optionObj.left) {
				//给指定左侧固定列节点添加固定列样式类
				fixedTableDomObj.$fixedLeftBox.addClass('fixed-table-left-box');
			}
			//如果开启了右侧固定列
			if (optionObj.right) {
				//给指定右侧固定列节点添加固定列样式类
				fixedTableDomObj.$fixedRightBox.addClass('fixed-table-right-box');
			}
			//给当前节点注册滚动事件
			$that.off('scroll.fixedTable').on('scroll.fixedTable', function () {
				scrollFn($(this), fixedTableDomObj);
			});
			//默认需要触发一次固定列计算函数
			scrollFn($that, fixedTableDomObj);
		});
		//如果有回调函数，则调用回调
		if (typeof optionObj.callBack === 'function') {
			optionObj.callBack($this);
		}
		return $this; //把当前节点返回，支持注册插件之后的后续链式调用其它jQuery方法
	},
	/**
	 * 获取多个对象的同一个属性值，返回一个list或null
	 * @param {string} name
	 * @return {array<string>|null}
	 */
	getAttrs: function(name){
		var list = [];
		this.each(function() {
			list.push($(this).attr(name));
		});
		return list.length ? list: null;
	}
});

/** 其它事件处理 fuyi 2023.06.15 **/
$(function () {
	/** 处理导航区域被原生下拉框覆盖的问题 **/
	// $(document).off('mousemove','#pageHeadNav').on('mousemove','#pageHeadNav',function () {
	// 	$('select').blur();
	// })
});
/**
 * 	产品编辑页产品属性添加自定义属性可编辑（暂放这里）
 *
 * 	init(option) 初始化注册
 * 		@option.nodeStr: 自定义属性值节点str
 * 		@option.comparisonKey: 默认text，处理属性值的方式 value、text 或者节点属性（‘data-name\data-value.....’）
 * 		@option.syncSetValue: 默认false，处理属性值的方式为节点属性时，是否同步设置value值 Boolean
 * 		@option.comparisonType: 默认str，取值类型，字符串（str）或编码（code）
 * 		@option.toLowerCase: 默认true，判断是否可以添加、更改时是否全转小写 Boolean
 * 		@option.showTitle: 默认false，更改时是否更新title值 Boolean
 * 		@option.editCall: 编辑成功加调，回传编辑节点$out和新值changeNameNew
 *
 * 	canAddProAttr($out, addVal, doChecked) 属性是否可以添加，返回Boolean
 * 		@$out: $node 节点外层
 * 		@addVal: String 添加的属性
 * 	 	@doChecked: Boolean 如果有相同的属性值，是否做选中处理
 *
 * 	速卖通\Shopee\Shopee全球\TikTok\TikTok全球\eBay\Daraz\全托管\Miravia\CSP
 * **/
var PRO_CUSTOM_ATTR_ADD = (function ($, win, doc) {
	var isClick = false,
		comparisonKey = 'text',
		syncSetValue = false,
		comparisonType = 'str',
		toLowerCase = true,
		showTitle = false,
		editCall = null,
		nodeStr = '<div class="change-box-out m-right20 changeBoxOut">' +
			'<label class="userDefaultBox">' +
			'<input class="m-right5 proAttrCheckbox" type="checkbox" value="0" checked>' +
			'<span class="checkboxName changeName"></span>' +
			'</label><div class="change-box proAttrChangeBox"><span class="iconfont icon_edit gray-b pointer v-middle btnEdit" title="编辑"></span></div></div>',
		proAttrChangeCon = '<div class="change-con changeCon">' +
			'<input class="form-component w170 changeIpt" type="text"/>' +
			'<span><span class="attach-icons md-18 icon-save btnSave" title="保存">save</span>' +
			'<span class="attach-icons md-18 btnClose" title="取消">replay</span></span></div>';

	var canAddProAttr = function ($out, addVal, doChecked) { //是否可以添加
			var flag = true,
				_v,
				_blo,
				_newVal = comparisonType === 'code' ? strToUc(addVal) : addVal;
			$.each($out.find('label'), function(i, j){
				_v = comparisonKey === 'text' ? $.trim($(j).text()) : comparisonKey === 'value' ? $(j).find('input:checkbox').val() : $(j).find('input:checkbox').attr(comparisonKey);
				if(_v){
					_blo = toLowerCase ? (_newVal.toLowerCase() === _v.toLowerCase()) : (_newVal === _v);
					if(_blo){
						flag = false;
						doChecked && $(j).find('input').prop('checked', true);
						return false;
					}
				}

			});
			return flag;
		},
		//单个编辑取消
		singleEditClose = function (obj, isCancel) {
			var $that = $(obj),
				$out = $that.closest('.changeBoxOut'),
				$changeName = $out.find('.changeName'),
				$changeBox = $out.find('.proAttrChangeBox'),
				$ipt = $out.find('.changeIpt'),
				oldVal = $ipt.attr('oldVal');

			$out.find('.btnEdit').removeClass('hide');
			$changeName.removeClass('hide');
			if(isCancel) {
				$changeName.text(oldVal);
				if(comparisonKey === 'value'){
					$out.find('input:checkbox').val(comparisonType === 'code' ? strToUc(oldVal) : oldVal);
				} else if(comparisonKey !== 'text' && comparisonKey !== 'value') {
					$out.find('input:checkbox').attr(comparisonKey, comparisonType === 'code' ? strToUc(oldVal) : oldVal);
				}
			}
			$changeBox.find('.changeCon').addClass('hide');
			$ipt.val('').attr('oldVal', '');
		},

		//单个编辑确定
		singleEditSave = function (obj) {
			if (!$(obj).is(':visible')) return;//防止失焦时误点，只有在输入框未关闭时处理保存
			var $that = $(obj),
				$out = $that.closest('.changeBoxOut'),
				$changeName = $out.find('.changeName'),
				changeNameNew = $.trim($out.find('.changeIpt').val());
			if(changeNameNew){
				if(canAddProAttr($(obj).closest('td'), changeNameNew, false)){
					$changeName.text(changeNameNew).attr('data-name', strToUc(changeNameNew));
					if(showTitle) $changeName.attr('title', changeNameNew);
					if(comparisonKey === 'value'){
						$out.find('input:checkbox').val(comparisonType === 'code' ? strToUc(changeNameNew) : changeNameNew);
					} else if(comparisonKey !== 'text' && comparisonKey !== 'value') {
						$out.find('input:checkbox').attr(comparisonKey, comparisonType === 'code' ? strToUc(changeNameNew) : changeNameNew);
						syncSetValue && $out.find('input:checkbox').val(changeNameNew);
					}
					if (editCall && typeof editCall === 'function') {
						editCall($out, changeNameNew);
					}
					singleEditClose(obj, false);
				} else {
					MYJ.message.error('属性值重复');
				}
			} else {
				MYJ.message.error('请输入属性值');
			}

		};


 	return {
		nodeStr: nodeStr,
 		init: function (_o) {
			if(_o){
				if(_o.nodeStr){
					nodeStr = _o.nodeStr;
					this.nodeStr = _o.nodeStr;
				}
				if(_o.comparisonKey) comparisonKey = _o.comparisonKey;
				if(_o.syncSetValue) syncSetValue = _o.syncSetValue;
				if(_o.comparisonType) comparisonType = _o.comparisonType;
				if(_o.toLowerCase) toLowerCase = _o.toLowerCase;
				if(_o.editCall) editCall = _o.editCall;
				if(_o.showTitle) showTitle = _o.showTitle;
			}
			//产品属性自定义值编辑
			$(doc).off('click', '.proAttrChangeBox .btnEdit').on('click', '.proAttrChangeBox .btnEdit', function () {
				var $that = $(this),
					$out = $that.closest('.changeBoxOut'),
					$changeName =$out.find('.changeName'),
					$changeBox = $out.find('.proAttrChangeBox'),
					oldVal = comparisonKey === 'text' ? $changeName.text() : comparisonKey === 'value' ? $out.find('input:checkbox').val() : $out.find('input:checkbox').attr(comparisonKey);
				if(comparisonType === 'code') {
					oldVal = ucToStr(oldVal);
				}
				if (!$changeBox.find('.changeCon').length) $changeBox.append(proAttrChangeCon);
				$that.addClass('hide');
				$changeName.addClass('hide').text('');
				if(comparisonKey === 'value') {
					$out.find('input:checkbox').val('');
				} else if(comparisonKey !== 'text' && comparisonKey !== 'value') {
					$out.find('input:checkbox').attr(comparisonKey, '');
				}
				$changeBox.find('.changeCon').removeClass('hide');
				var $changeIpt = $changeBox.find('.changeIpt');
				$changeIpt.attr('oldVal', oldVal).val(oldVal).focus().select();
				if (typeof _o.editBeforeCall === 'function') {
					_o.editBeforeCall($changeIpt);
				}
			});

			//产品属性自定义值取消
			$(doc).off('click', '.proAttrChangeBox .btnClose').on('click', '.proAttrChangeBox .btnClose', function () {
				isClick = true;
				singleEditClose(this, true);
			});

			//产品属性自定义值确定
			$(doc).off('click', '.proAttrChangeBox .btnSave').on('click', '.proAttrChangeBox .btnSave', function () {
				isClick = true;
				singleEditSave(this);
			});

			//产品属性自定义值输入框回车
			$(doc).off('keydown', '.proAttrChangeBox .changeIpt').on('keydown', '.proAttrChangeBox .changeIpt', function (e) {
				var key = window.event ? e.keyCode : e.which;
				if(key && +key === 13){
					singleEditSave(this);
				}
			});
			$(doc).off('input', '.proAttrChangeBox .changeIpt').on('input', '.proAttrChangeBox .changeIpt', function (e) {
				var objVal = $(this).val();
				//替换特殊空格
				objVal = MYJ.regTest({
					str: objVal,
					testType: 'nbsp',
					isReplace: true,
					replaceStr: ' '
				});
				//去除不可见字符
				objVal = MYJ.regTest({
					str: objVal,
					testType: 'notVisible',
					isReplace: true
				});
				$(this).val(objVal);
			});
			$(doc).off('focus', '.proAttrChangeBox .changeIpt').on('focus', '.proAttrChangeBox .changeIpt', function () {
				isClick = false;
			});
			//产品属性自定义值编辑失焦
			$(doc).off('blur', '.proAttrChangeBox .changeIpt').on('blur', '.proAttrChangeBox .changeIpt', function () {
				var _this = this;
				setTimeout(function () {
					if (isClick) return;//点击取消，拦截继续执行失焦保存的方法
					if($.trim($(_this).val())){
						singleEditSave(_this);
					}
				}, 300);

			});
		},
		canAddProAttr: canAddProAttr
	}
})(jQuery, window, document);


